|
ROLLBACK транзакций в цикле для PosgreSQL - как правильно делать?
|
|||
---|---|---|---|
#18+
Скрипт написан на PHP. В нем есть PHP-цикл, который выполняет порцию из ~1000 отдельных INSERT. Отдельные INSERT (а не один большой) сделаны вот по какой причине: некоторые INSERT могут завершиться ошибкой, например если значение вставляемого поля не уникально для поля с флагом UNIQUE (у меня это поле содержит uuid). Такие ошибки надо просто проигнорировать. После этих INSERT-ов, в другую, сервисную, таблицу записывается последний корретно добавленый uuid. Это нужно из-за того, что данные для очередной порции INSERT могут вытягиваться с разных хостов, и для каждого такого хоста хранится свой uuid. В любом случае, 1000 INSERT-ов и команда UPDATE для сохранения uuid, должны оборачиваться в одну транзакцию. Это нужно для сохранения консистенции данных. Проблема в том, что если при выполнении какого-то INSERT совпадет uuid, то будет ошибка, и будет откатана ВСЯ транзакция. Чтобы это обойти, я хочу воспользоваться SAVEPOINT. То есть, сделать перед INSERT команду SAVEPOINT, и если INSERT завершился ошибкой, сделать ROLLBACK. Но я читаю документацию, и не могу понять, как это правильно сделать. У меня есть два варианта: Вариант первый - простой: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Вариант второй - каждый раз удалять SAVEPOINT: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Тут есть две непонятки. Непонятка первая: Вроде как написано, что не может быть несколько точек сохранения под одним и тем же именем, поэтому удаление SAVEPOINT в цикле - необходимо. С другой стороны, SAVEPOINT с одним и тем же именем должен быть _один_ в пределах одной транзакции, а мы в цикле таки создаем SAVEPOINT с одним и тем же именем. То есть тут вопрос, а можем ли мы в принципе создавать SAVEPOINT в пределах одной транзакции с одним и тем же именем, даже если мы его и удаляем, или надо все время генерить SAVEPOINT с разными именами ? Непонятка вторая: Я пока что склоняюсь, что вариант кода 2 должен быть рабочим. Но хотелось бы узнать, что лучше по производительности : постоянно создавать и удалять SAVEPOINT, или создавать SAVEPOINT с разными именами (например beforeInsert0, beforeInsert1, ... beforeInsertN), и они потом сами удалятся при завершении транзакции? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 15:14 |
|
ROLLBACK транзакций в цикле для PosgreSQL - как правильно делать?
|
|||
---|---|---|---|
#18+
Что за форма регистрации, Я бы просто проверял наличие конфликтующей записи перед тем как insert делать. Будет СИЛЬНО быстрее чем savepoints которые дорогие изрядно. Как вариат еще before insert триггер на таблице с такой же логикой (тогда с приложения вообще ничего проверять не надо). ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 15:19 |
|
ROLLBACK транзакций в цикле для PosgreSQL - как правильно делать?
|
|||
---|---|---|---|
#18+
Что за форма регистрации Такие ошибки надо просто проигнорировать. on conflict do nothing ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 15:44 |
|
ROLLBACK транзакций в цикле для PosgreSQL - как правильно делать?
|
|||
---|---|---|---|
#18+
Что за форма регистрации, ну и имечко у тебя ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 16:20 |
|
ROLLBACK транзакций в цикле для PosgreSQL - как правильно делать?
|
|||
---|---|---|---|
#18+
Melkij Что за форма регистрации Такие ошибки надо просто проигнорировать. on conflict do nothing там 9.1 версия и не меняется )) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 17:06 |
|
ROLLBACK транзакций в цикле для PosgreSQL - как правильно делать?
|
|||
---|---|---|---|
#18+
mefman, Я его получил когда глючила форма регистрации на этом форуме, теперь поменять не могу, ибо это не предусмотрено в движке. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 17:35 |
|
ROLLBACK транзакций в цикле для PosgreSQL - как правильно делать?
|
|||
---|---|---|---|
#18+
Что за форма регистрации mefman, Я его получил когда глючила форма регистрации на этом форуме, теперь поменять не могу, ибо это не предусмотрено в движке. Не могу исправить даже модератором, придется с этим жить. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2020, 18:16 |
|
|
start [/forum/topic.php?fid=53&msg=39936058&tid=1994782]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
53ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
47ms |
get tp. blocked users: |
1ms |
others: | 285ms |
total: | 429ms |
0 / 0 |