|
|
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Всем привет. Я давно не имел дела с SQL. Пишу простенькую клиент-серверную программу на Java с хранением данных в MySQL. Есть java-сервлет, который получает от множества клиентских приложений данные (допустим это 10 штук в секунду от 1000 клиентов, т. е. в среднем каждый клиент посылает данные 1 раз за 100 сек.). Этот сервлет сохраняет эти данные в БД в некую таблицу TempTable. Также есть на сервере есть программа, которая раз в несколько секунд (например раз в 1 секунду). 1. Читает ВСЕ записи в таблице TempTable 2. Сохраняет их в таблицу операций OperationTable, а также сохраняет в памяти 3. Удаляет все записи из таблицы TempTable 4. дальнеяшая обработка данных из памяти. Вопрос тут и по Java и по особенностям MySQL. Как мне защитить систему от потери данных. Например п. 3 удаляет все записи из временной таблицы, но пока работал п.2 мы получили запрос от клиента и добавили запись в соответствии с п. 1. и получается, что эту новую запись мы удалили и она так и не появилась в п. 2 и 4. Я так понимаю, что пока работают п. 1-3 надо заблокировать таблицу TempTable от других операций и если приходит новый запрос от клиента, он должен встать в очередь (а не сделать запись и не вывалить исключение). Вопрос в том, как это реализовать. Средствами MySQL или на Java есть инструменты, получающие эксклюзивный доступ к таблице на время выполнения нескольких операций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 13:13:23 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Geronemo, а вы пишите во врем.таблицу время появления каждой записи (добавьте в таблицу поле timestamp defaul current_timestamp) и обрабатывайте каждый раз, допустим, не все записи, а только те, что старше (текущее время - интервал запуска батча) думаю, отставание в 1 секунду будет некритично, а другие варианты будут куда замороченнее ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 13:21:32 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
мдя...он походу никогда не имел дело с sql :) - исходя из постановки вопроса, только начал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 13:27:39 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
alex564657498765453мдя...он походу никогда не имел дело с sql :) - исходя из постановки вопроса, только начал. Имел дело несколько лет назад, но даже тогда это не было моей прямой обязанностью. Просьба писать по существу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 13:53:27 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Придумал еще одно решение проблемы. У меня в таблице TempTable есть id auto_increment И это поле я также читаю и сохраняю для последующей обработки. В принципе, в п. 3. удаление записей я могу сделать по списку этих id Но может можно сделать проще средствами java (Вопрос к знатокам java) допустим такой код (1) Statement statement = сonnection.createStatement() .... Чтение всех данных из TempTable .... Запись данных в OperationTable .... Удаление всех записей из TempTable (N) statement.close() Можно ли на участке кода от строчки кода номер 1 до N зпретить кому бы то ни было извне обращаться к таблице TempTable ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 14:48:56 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
на чтение - нет посмотри в сторону хранимых процедур- возможно в них логику перенести и будет тебе счастье. а решение 16430816 лучший вариант. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 15:53:30 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Geronemo, 16430816 -- стандартное хорошее решение. (Есть варианты, например с дополнительной колонкой статуса) Алаверды : предложеное решение отличается от того что вы спрашиваете по нескольким позициям: 1. вместо работы со всей таблицей у вас есть гибакая возможность обрабатывать очередь по частям, возможно даже в несколько потоков. 2. Блокировка переносится с "физической" базы в логику аппликации -- больше контроля и гибкости. 3. Логическая блокировка (по ид, таймстампу, по колонке статуса) может длится как угодно долго. Долгие физические блокировки крайне не рекомендуются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 18:58:26 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Вариант с timestamp мне не очень понравился. Я добавил поле curenttime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP Увеличил интервал обращения сервера к таблице TempTable до 10 сек. Запустил эмулятор клиентских приложений и сервер на несколько секунд, чтобы сервер записал обращения клиентов, но ни разу не обработал эти данные (п. 1-3 из 1-го сообщения). Затем я вручную пошел и посмотрел содержимое таблицы TempTable и увидел кучу сообщений со значением '2014-08-12 21:05:50' в поле curenttime, также куча записей со значением '2014-08-12 21:05:51' ,'2014-08-12 21:05:52' и т. д. Такой вариант меня не устраивает. Если бы писали миллисекунды, то можно бы было разграничить данные. А так может получиться, что сервер извлекает все данные вплоть по '2014-08-12 21:05:54', например, и пока он сих обрабатывает клиентские приложения сделают еще несколько запросов и они будут датированы этим же значением '2014-08-12 21:05:54'. И мы удалим в том числе и их. Может есть какая-нибудь функция, дающая более точное время, с миллисекундами. Или же я что-то не так понимаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 21:32:42 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Geronemo, Поставьте верхний предел обработки как текушее время МИНУС одна (или 3, если нервы дроже) секунда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 21:39:11 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Geronemo, две временные таблицы. > Также есть на сервере есть программа, которая раз в несколько секунд (например раз в 1 секунду). 1. Сообщает сервлету, что начинает чтение из таблицы [1] (сервлет начинает писать в таблицу [2]). Читает ВСЕ записи в таблице [1] 2. Сохраняет их в таблицу операций OperationTable, а также сохраняет в памяти 3. Удаляет все записи из таблицы [1] 4. дальнеяшая обработка данных из памяти. 5. Сообщает сервлету, что начинает чтение из таблицы [2] (сервлет начинает писать в таблицу [1]) ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 23:18:39 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Спасибо. Все заработало. Надо еще какое-то время погонять, чтобы убедиться, что данные не пропадают, но в целом думаю, что все норм. Есть еще один вопрос, не буду создавать новую тему. Что вы думаете по поводу Java Hibernate, стоит ли заморачиваться с ним, когда у меня БД очень простая. Или же лучше всегда использовать Hibernate, просто потому что так правильнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 23:28:43 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Stupid_BOT, временная таблица у меня одна. Та, 2-я это итоговая таблица, куда скидываются все данные от клиентов, а также потом происходит некоторая их обработка (а конкретно модификация одного поля - Статус, который мжет иметь несколько значений, типа 'В процессе', 'успешно', 'ошибка'....) Возвращать результат обработки клиенту задачей не предусмотрено. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2014, 23:35:57 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Geronemo, я так понял, что и сервлет, и "серверная" программа - оба могут быть Вами модифицированы. И предложил вариант с переключением временных таблиц. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 00:04:54 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
GeronemoСпасибо. Все заработало. Надо еще какое-то время погонять, чтобы убедиться, что данные не пропадают, но в целом думаю, что все норм. Есть еще один вопрос, не буду создавать новую тему. Что вы думаете по поводу Java Hibernate, стоит ли заморачиваться с ним, когда у меня БД очень простая. Или же лучше всегда использовать Hibernate, просто потому что так правильнее. Нету такого понятия как "правильнее". Все "зависит от". Для расширения кругозора кибернат ооочень полезен, как и знать что такое обжект-релейшнл мапинг (ORM). Конкретно к вашему проекту -- 2 таблицы и 3 класса -- нафик не надо, но если есть время -- сделайте в отдельном бранче, что бы знать на будушее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 00:22:43 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
0. начать транзакцию. 1. Читать по одной записи в таблице TempTable. читать с for update. 2. Сохранять их в таблицу операций OperationTable, а также сохраняет в памяти 3. Удалять только что обработанную запись из таблицы TempTable 4. делать это все в цикле, пока есть записи. 5. при окончании набора входных записей завершить транзакцию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 00:23:37 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Geronemo, вообще, тут напрашивается для использования jms, и никаких прямых работ с бд. правда, транзакции и там нужны будут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 00:27:17 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
GeronemoЕсли бы писали миллисекунды, то можно бы было разграничить данные. А так может получиться, что сервер извлекает все данные вплоть по '2014-08-12 21:05:54', например, и пока он сих обрабатывает клиентские приложения сделают еще несколько запросов и они будут датированы этим же значением '2014-08-12 21:05:54'. И мы удалим в том числе и их. Может есть какая-нибудь функция, дающая более точное время, с миллисекундами.Почему вы считаете, что миллисекунды совпасть не могут? :) javajdbcGeronemo, Поставьте верхний предел обработки как текушее время МИНУС одна (или 3, если нервы дроже) секунда.Я об этом уже писал, кстати. В том самом посте. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 10:24:59 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
MasterZiv0. начать транзакцию. 1. Читать по одной записи в таблице TempTable. читать с for update. 2. Сохранять их в таблицу операций OperationTable, а также сохраняет в памяти 3. Удалять только что обработанную запись из таблицы TempTable 4. делать это все в цикле, пока есть записи. 5. при окончании набора входных записей завершить транзакцию. Спасибо за предложенный вариант, но тут есть нюансы, а которых я не указал первоначально. Возникает вопрос о быстродействии, если повысить частоту получения данных от клиентов. + у меня п. 1. организован таким образом, что в цикле происходит select * TempTable where operation_type = "несколько видов операций". Мне разделение по типам операций нужно, чтобы создать несколько массивов однотипных данных и отправлять обработчикам их массивами, а не по по одному. В вашем варианте, как мне кажется можно было бы обойтись вообще без TempTable, просто писать сразу в таблицу OperationTable и добавить в поле статуса вариант значения "данные только что получены от клиента" и потом апдейтить его. Весь смысл существования временной таблицы в том, что на входе у нас запросы от тысяч клиентов, а на выходе мы должны отослать данные небольшому количеству внешних серверов неким пакетом и получить ответ. Для этого я накапливаю большое количество записей во временной таблице, а потом раз в несколько секунд извлекаю их оттуда, группирую по типу операций и делаю всего штук 5-10 запросов на внешние серверы. Я так понимаю, что процесс извлечения данных из БД происходит значительно быстрее, чем установка соединения с внешним сервером (которых было бы тысячи). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 11:53:04 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
tanglir, спасибо за совет. Никто у вас не отнимает лавры, просто я ваше предложение, похоже, не совсем внимательно изучил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 11:55:30 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
MasterZivGeronemo, вообще, тут напрашивается для использования jms, и никаких прямых работ с бд. правда, транзакции и там нужны будут. тут у меня дело в том, что клиенты и внешние серверы это программы, написанные сторонними людьми (я пока что эмулирую их), я не могу повлиять на их внешний интерфейс, мне его представляют как данность. И мое серверное приложение должно брать на себя ответственность за доставку данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 12:00:53 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Geronemo И мое серверное приложение должно брать на себя ответственность за доставку данных. + сохранение ответов от внешних серверов и ведение всякого рода отчетности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 12:11:24 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Сделал проверку системы. 50000 запросов и ни один не потерялся. Но тут у меня возникает еще один вопрос. Через день непрерывной работы (а именно такая и предполагается ) в таблице OperationTable будет несколько миллионов записей. Сдается мне, что с т. з. быстродействия с этим надо что-то делать. Например, завести 3-ю таблицу ArchiveOperationTable, куда перемещать данные раз в сутки из OperationTable. Но тут возникает еще 2 вопроса . 1 . Когда-нибудь таблице ArchiveOperationTable будут миллиарды записей и она будет раз в сутки пополняться на несколько миллионов. Возможны ли тут висяки ? Или нехватка дискового пространства . Как с этим борются в реальных системах. Держать архив за месяц ? Но не хотелось бы удалять данные даже через год. Возможное решение - сделать отдельный сервер (физический сервер + прорамму сервер), который будет раз в сутки извлекать данные с нашего сервера и опустошать таблицу OperationTable (можно предшествующие сутки, т. е. данные за последние сутки оставлять в OperationTable, а все что раньше отправлять). А на этом новом сервере пусть уже будет много HDD и он сам будет разбираться с архивом. Там быстродействие большое не нужно, все-таки обращение к этому серверу не будет в реальном времени, а скорее администраторы системы будут проверять какие-то ошибки и делать это чуть ли не вручную (например, найти транзакцию с id = 123456789) и посмотреть ее детали. 2. Допустим мы раз в сутки (допустим наступило 13.08.2013, 00:00:00) делаем такую последовательность операций 1. Читаем все операции до 12.08.2013, 00:00:00 2. Отправляем их на архивный сервер (вот тут я в сомнениях - может все же сервер должен быть один, как и БД) 3. Удаляем все операции, датированные ранее 12.08.2013, 00:00:00 На практике мы будем иметь такую картину. Раз в полночь несколько миллионов записей читаются из таблицы OperationTable, а затем они же оттуда удаляются. Т. е. происходит 2 большие операции над таблицей. Но клиенты в полночь спать ведь не ложатся. Они будут все так же обращаться к нашему серверу и мне хотелось бы понять, возможно ли в это время зависание или падение системы и если ДА, то как с этим можно бороться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 13:36:20 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
GeronemoСделал проверку системыВы уж пишите, какой вариант проверяете - мой, мастерзива или какой-то ещё. Geronemoто как с этим можно боротьсяА что мешает запускать удалятор раз в минуту, например? И чистить им записи опять же старше минуты. Или вообще объединить выборку с удалением? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 13:51:40 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
tanglirGeronemoСделал проверку системыВы уж пишите, какой вариант проверяете - мой, мастерзива или какой-то ещё. Ваш вариант, конечно. Очень удобно и быстро. Спасибо. Geronemoто как с этим можно боротьсяА что мешает запускать удалятор раз в минуту, например? И чистить им записи опять же старше минуты. Или вообще объединить выборку с удалением? Ну тут такой момент. За внешние серверы мы не отвечаем, они могут прислать ответ и через 3 часа (серверы Вконтакте из-за жары, например, были недоступны несколько часов около 2-х недель назад). А вообще я не знаю, как тут лучше быть. Архивная таблица нужна, как и удалятор, но как их лучше сконфигурировать, это надо хорошо подумать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 14:12:37 |
|
||
|
Вопрос о целостности данных. 2 процесса и несколько операций над таблицами.
|
|||
|---|---|---|---|
|
#18+
Geronemo, то есть имелась в виду чистка уже той таблицы, куда записи пришли? я думал, речь про исходную, куда они со всех серверов валятся. ну если у вас не майисам, то удаление пусть даже и миллиона записей на скорость работы если и повлияет, то слабо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2014, 19:11:30 |
|
||
|
|

start [/forum/topic.php?fid=47&tid=1832955]: |
0ms |
get settings: |
8ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
44ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
66ms |
get tp. blocked users: |
2ms |
| others: | 254ms |
| total: | 407ms |

| 0 / 0 |
