|
|
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Доброго времени суток. Нужна помощь, как правильно алгоритмически решить следующую задачу: Есть несколько файлов размером до 500 Мб, необходимо распарсить каждый файл в отдельном потоке и записать их все в одну таблицу, при этом если возникли проблемы при парсинге или записи в таблицу, то нужно удалить все вставленные данные до появления ошибки. После того как содержимое конкретного файла было обработано и вставлено в таблицу необходимо для вставленных данных для каждого файла заполнить колонку вычислив значение и если обновление прошло успешно то пометить что файлы были записаны корректно и удалить файл Я попробовал решить это следующим образом БД MSSQL и java - Создаю поток и в нем делаю следующее - Открываю коннект к БД и ставлю autocommit=false - читаю файл по строчкам и делаю по строчкам insert в таблицу - После того как пробежался по всем строчкам вызываю UPDATE в котором заполняю колонку (с помощью ROW_NUMBER() OVER (PARTITION BY ___ order by__ ) - Далее вызываю Commit и поток завершает свою работу Это все прекрасно работает если файл один, но если я открываю три файла и каждый в отдельном потоке, то после завершения первого потока почему-то два других потока выдают ошибку Exception:java.sql.SQLException: Invalid state, the Connection object is closed. Как такое может происходить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2014, 20:59 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Извиняюсь, не ту ошибку скопировал Exception:java.sql.SQLException: Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. Вопрос, как мне избавится от деадлоков? Может Isolation LEVEL изменить или еще что-то? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2014, 21:11 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
надо использовать разные Connection для каждого потока, ну и соотвественно коннекшен пул ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2014, 21:42 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
ааа ну так это все меняет. Попробуй не писать каждый инсерт сразу а собрать их все вместе, и потом записывай. Гугли BatchInsert, таким образом риск дедлоков уменьшится. Хотя сама ошибка никуда не уйдет, тут надо смотреть что именно лочится, и почему дедлок средствами бд ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2014, 21:44 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2014, 21:47 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
забыл ник, С конфетками вроде разобрался) Остались deadlock! Я понимаю что лочится из-за апдейта, который я выполняю, но как тут быть непонятно. Суть проблемы в том, что одновременно инсертятся данные из трех потоков в одну таблицу, а потом мне нужно сделать update, который апдейтит данные вставленные в таблицу внутри каждого потока. Update выглядит следующим образом: Код: sql 1. 2. 3. 4. 5. Вроде от deadlock получилось избавиться с помощью Isolation level SNAPSHOT. На небольших файлах работает хорошо. Но при вставке 3х файлов по 400 мб выскакивает ошибка: Exception:java.sql.SQLException: The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions. То ли я очень сильно нагружаю БД, то ли изначально подход неправильный к решению ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2014, 23:44 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
jeddite, кто мешает отделить мух от котлет? Потоками разбери файлы в один массив (если хватит оперативки). А потом батчем за раз вставь в БД его форматом и максимально быстро. Либо разбирайся с локами. На блокировочнике ты всегда можешь схватить в неожиданном месте. .... Зачем бить на потоки задачу, если все файлы в одном откате и транзакции? авторесли обновление прошло успешно то пометить что файлы были записаны файлы или файл? ЗЫ. Про коннект в потоке верно сказали. ... Ещё можно готовить файлы во временной табле, а потом одним запросом перебросить в основную. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2014, 23:53 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
jedditeUpdate выглядит следующим образом на ветке по БД закинь вопрос по запросу ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2014, 23:57 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
jeddite, Приведите нормальный запрос, который хотя бы будет синтаксически верным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 00:34 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Petro123, Оперативки то и не хватит т.к. файлы по 500 мб и сейчас их три а может быть и больше. batch можно частями выполнять и наверно перепишу код. и как я уже писал файлы должны обрабатываться отдельно и возможно в разное время Вот можно ли insert с апдейтом объединить ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 00:38 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Petro123На блокировочнике ты всегда можешь схватить в неожиданном месте. Ну как бы jeddite Isolation level SNAPSHOT не совсем про блокировочник. А к операциям по конкурентному изменению данных и возникающих при этом deadlock'ах это имеет еще меньшее отношение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 00:42 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Локшин Марк, Вот этот запрос используется, взял из лога Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 00:49 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Локшин МаркPetro123На блокировочнике ты всегда можешь схватить в неожиданном месте. Ну как бы jeddite Isolation level SNAPSHOT не совсем про блокировочник. А к операциям по конкурентному изменению данных и возникающих при этом deadlock'ах это имеет еще меньшее отношение. Ну почему же не про блокировки? При таком подходе каждый поток работает со своим snapshot и блокировок не происходит ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 01:16 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
jeddite, Сколько вы записей апдейтите? Посмотрите тут еще http://www.sqlusa.com/bestpractices/largeupdate/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 01:52 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
YamahaR1, Где-то 1 900 000 записей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 02:06 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
jedditeИзвиняюсь, не ту ошибку скопировал Exception:java.sql.SQLException: Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. Вопрос, как мне избавится от деадлоков? Может Isolation LEVEL изменить или еще что-то? убери UPDATE из этой транзакций. либо сразу при insert генерируй значение этого поля либо делай это в отдельной транзакции . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 10:11 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
MasterZiv, У меня задача отслеживать целостность данных и если апдейт в отдельную транзакцию вынести, то как контролировать целостность..мне нужно быть уверенным на 100 процентов, что данные закомитятся только в том случае если апдейт был выполнен...не используя одну большую транзакцию это можно как-то сделать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 11:56 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
1. Если при разборе могут быть ошибки, то сначала должен делаться разбор файла и только после этого должна начинаться вставка подготовленных значений. 2. Никаких "сначала вставка, потом обновление" быть не должно. Если в процессе вставки обнаружена проблема, то rollback откатывает всю транзакцию, если проблем не было, то commit фиксирует всю транзакцию. Со всеми актуальными значениями. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 14:46 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
jedditeНу почему же не про блокировки? При таком подходе каждый поток работает со своим snapshot и блокировок не происходит Вот именно, что пассаж про блокировочник здесь не к месту. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2014, 21:41 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Локшин МаркjedditeНу почему же не про блокировки? При таком подходе каждый поток работает со своим snapshot и блокировок не происходит Вот именно, что пассаж про блокировочник здесь не к месту. угу. Верю, что на миллионах записей, сиквел одной галкой превращается в оракл (неБлокировочник). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2014, 00:08 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
jedditeИзвиняюсь, не ту ошибку скопировал Exception:java.sql.SQLException: Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. Вопрос, как мне избавится от деадлоков? Может Isolation LEVEL изменить или еще что-то? На SQL Server так лучше не делать совсем. Множество долгоживущих транзакций вставляющих в одну таблицу. Вы никогда таким образом дедлоки не разрулите. Я бы завел временную таблицу для каждого Thread/Connection и писал бы все данные в эту таблицу. Временная таблица у каждого Connection своя. При ошибке, временную таблицу можно удалить. Да, она и сама умрет при закрытии соединения. А вот при завершении обработки нужно вызвать одну быструю операцию копирования из временной таблицы в основную. Тогда потоки никак не будут мешать друг другу. И не будет длинных транзакций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2014, 09:29 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Petro123Локшин Маркпропущено... Вот именно, что пассаж про блокировочник здесь не к месту. угу. Верю, что на миллионах записей, сиквел одной галкой превращается в оракл (неБлокировочник). И как же ваш неБлокировочнир разруливает конкурентные UPDATE'ы? Наверное версиями? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2014, 21:17 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
BlazkowiczjedditeИзвиняюсь, не ту ошибку скопировал Exception:java.sql.SQLException: Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. Вопрос, как мне избавится от деадлоков? Может Isolation LEVEL изменить или еще что-то? На SQL Server так лучше не делать совсем. Множество долгоживущих транзакций вставляющих в одну таблицу. Вы никогда таким образом дедлоки не разрулите. Я бы завел временную таблицу для каждого Thread/Connection и писал бы все данные в эту таблицу. Временная таблица у каждого Connection своя. При ошибке, временную таблицу можно удалить. Да, она и сама умрет при закрытии соединения. А вот при завершении обработки нужно вызвать одну быструю операцию копирования из временной таблицы в основную. Тогда потоки никак не будут мешать друг другу. И не будет длинных транзакций. Ну а если например будет производиться одновременное копирование данных из трех потоков в одну таблицу, это не приведет к дедлоку? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2014, 01:22 |
|
||
|
Запись из разных потоков в одну таблицу
|
|||
|---|---|---|---|
|
#18+
Локшин Марк, Устройство БД, JS и т.д. в соседней ветке. Java эффективно делает crud а не ETL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2014, 08:17 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38799588&tid=2126293]: |
0ms |
get settings: |
9ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
441ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
82ms |
get tp. blocked users: |
1ms |
| others: | 214ms |
| total: | 782ms |

| 0 / 0 |
