|
|
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
Привет, Такая ситуация: есть две таблицы: А и Б Записи в Б могут удаляться двумя путями: напрямую из таблицы Б и при удалении родительской записи в А по foriegn key. На таблице Б есть тригер, который апдейтит родительскую запись, при удалении записи в таблице Б. Если удалять напрямую из Б, то все хорошо. Если же удалять из А, то записи в Б удаляются, а сама запись в А - нет. Видимо потому, что в момент удаления из Б, срабатывает тригер, который апдейтит запись в А, и она после этого уже не удаляется. Вопрос: правильно ли я понимаю причину не удаления записи из А? Что можно с этим сделать? Апдейт таблицы А нужен, от него не уйти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.07.2014, 17:00:05 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
Anton Laflaf, ИМХО, надо смотреть триггеры, когда они выполняются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2014, 08:32:25 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
roadster, и на А и на Б тригеры выполняются before Но меня удивляет сам факт, что апдейт записи отменяет его удаление ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2014, 13:39:27 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2014, 13:55:44 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
Anton Laflaf, тексты триггеров можно посмотреть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2014, 21:58:51 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
Не вижу ничего необычного. PostgreSQL версионный в общем понимании этого слова; Разбираем по операциям, очень грубо без сильной детализации: - DELETE строки A таблицы T1; - - Поиск строки A - нашли строку версии N (последнюю); - - Запуск триггера BEFORE DELETE для строки A; - - - DELETE строки B таблицы T2; - - - - Поиск строки B - нашли строку версии M (последнюю); - - - - Запуск триггера BEFORE DELETE для строки B; - - - - - UPDATE строки A таблицы T1; - - - - - - Поиск строки A - нашли строку версии N (последнюю, она еще не удалена, и доступна в пределах этой транзакции); - - - - - - Запись обновленной строки A версии N + 1 (теперь эта последняя); - - - - - - Помечаем строку A версии N как удаленную; - - - - Возвращаем из триггера OLD и помечаем строку B версии M как удаленную; - - Возвращаем из триггера OLD и помечаем строку A версии N как удаленную, повторный поиск новой версии строки N + 1 естественно не производится; В итоге получаем: строка A версии N - помечена как удаленная (2 раза); строка B версии N - помечена как удаленная; строка A версии N+1 - обновленная строка; Можно теперь перестроить индексы. Можно, конечно начать флейм о том какой PostgreSQL тупой, но не он осуществляет неконтролируемые перекрестные операции над строкой. Собственно таков принцип работы триггеров BEFORE: сначала строку находим, исполняем триггер, потом производим операцию над найденной строкой, то что появилась новая версия строки - триггеру не ведомо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.07.2014, 10:59:50 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
Phoinix, "стройная теория, май френд, бат древо жызни, таки, зеленеет": Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. (?) ЧЯДНТ 2ТС приведите таки ваши триггера. там где-то есть, где покопаться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.07.2014, 13:34:27 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
to qwwq Вообще-то сарказм неуместен, а стоило бы немного почитать теорию. С данным эффектом я сталкивался на версии на более ранних версиях. Кстати в 9.3 этот эффект исправили путем запрета: ERROR: tuple to be updated was already modified by an operation triggered by the current command HINT: Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows. Какая версия у вас, тот еще вопрос. to All В любом случае. Суть не в том, как это происходит (хотя это полезно знать), а в том, что не контролируемые перекрестные/рекурсивные/каскадные команды - зло, и стоит быть несколько внимательным когда используются триггера. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.07.2014, 15:12:33 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
PhoinixС данным эффектом я сталкивался на версии на более ранних версиях. Автор темы описывает другой случай и по его описанию воспроизвести у меня тоже не получается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.07.2014, 16:00:23 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
Phoinix, код где ? что нужно AFTER -- известно. что ошибка в BEFORE обсуждалась тут же (в т.ч. проблемы на версиях до 9.?. и запрет после) -- помню, но по тексту ошибки не нахожу. (они его не изменили ?) Т.ч. чего именно она касается - не совсем ясно. //в нашем случае она не возникает. зато в моем кейсе отваливается pk "on update cascade" -- при попытке апдейта пк в ведущей (А), что подтверждает рекомендацию в тексте ошибки Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. -- т.е. все чудесатей и чудесатей (при хватании себя за хвост через before триггера) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.07.2014, 17:01:51 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
Phoinix- - Поиск строки A - нашли строку версии N (последнюю); упс... - - Запуск триггера BEFORE DELETE для строки A; - - - DELETE строки B таблицы T2; - - - - Поиск строки B - нашли строку версии M (последнюю); - - - - Запуск триггера BEFORE DELETE для строки B; - - - - - UPDATE строки A таблицы T1; очень странное рассуждение. я не знаток постгре, но версионность сервера сказывается прежде всего на том, что читающие транзакции не мешают пишущим и не более того. теперь поподробнее опишу что я вижу в Вашем рассуждении. на месте вставленного мной упс найденная строка должна быть удалена, ну или "помечена" на удаление в ожидании коммита или роллбэка - это обязательное условие для срабатывания триггера. так вот эта "помеченная" на удаление строка может быть прочитана читающей транзакцией без проблем. но вот в последней выделенной строке должен, нет, просто обязан возникнуть лок конфликт. поэтому Ваши рассуждения сомнительны. к тому же, если бы было возможным выполнение описанной Вами цепочки действий, то это означало бы,что пишущие транзакции не мешают пишущим, что повлекло бы за собой возможность нескольким транзакциям поменять запись одновременно, но тогда необходимо наличие механизма многоверсионности закоммиченных данных, я бы назвал это разными инкарнациями записи (грубо с одним значением ПК было бы несколько валидных и видных читателям записей). Вы не находите эту ситуацию глупой в разрезе существующей методологической базы реляционных СУБД? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.07.2014, 23:12:17 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
Phoinix, прошу прощения, написал глупость. лок конфликт возникает в рамках межтранзакционного (если так можно выразиться) взаимодействия. соответственно внутри транзакции все изменения будут видны, но тем не менее по триггеру бефор данные проапдейтятся, но потом удалятся (есть ещё вариант зацикливания, но автор топика об этом не говорит). так что в любом случае описанная Вами ситуация невозможно. Необходимо смотреть триггеры, без них ничего не понятно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2014, 08:19:12 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
По моему, сейчас все говорят не о том. Резать проблему которая заведомо неверна - неправильно. Решение простое: поменять BEFORE на AFTER для таблицы A. Либо, если надо, разделить триггерную функцию на две, оставить часть отвечающую за проверку состояния перед удалением в BEFORE, а часть отвечающую за удаление связанных строк в AFTER. Все остальное - домыслы. Пытаться понять, почему БД работает неадекватно при неправильном решении задачи, конечно, можно, но, как показывает флейм в данном топике, результат у каждого разный, зависит от версии и расположения звезд на небе. Почему такая проблема может возникать, я пусть и грубо - написал: В итоге получаем: строка A версии N - помечена как удаленная (2 раза); строка B версии N - помечена как удаленная; строка A версии N+1 - обновленная строка; Как будет на этот итог реагировать БД - логично не предсказуемо. В своей практике я использовал не совсем верные решения с условной предсказуемостью для определенной версии, но при обновлении БД, практически всегда сталкивался с проблемами связанными с этими неправильными решениями. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2014, 11:25:42 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
PhoinixПо моему, сейчас все говорят не о том.без текстов триггеров разговаривать не о чем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2014, 11:51:01 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
roadsterPhoinixПо моему, сейчас все говорят не о том.без текстов триггеров разговаривать не о чем. не, дон местами прав, помню было где-то обсуждалово, но вот найти не могу (но что-то было, точно). // там довольно нетривиально внутри всё происходило, "как не в одном потоке". если я правильно помню. В моем случае кейс построен наполовину -- FK генерирует AFTER триггера: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. т.е. если у ТС еще и каскады самописные и именно BEFORE -- может быть всякое интересное. но хотелось бы посмотреть на тексты триггеров ТС, хотя бы модельные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2014, 12:22:41 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
qwwq// там довольно нетривиально внутри всё происходило, "как не в одном потоке". если я правильно помню.при чём здесь потоки? или я не понимаю о каких потоках идёт речь. qwwqно хотелось бы посмотреть на тексты триггеров ТС, хотя бы модельные.я это и говорю, без них дальнейшее обсуждение бесполезно, догадок можно настроить кучу и все они окажутся неверными. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2014, 13:03:58 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
roadsterqwwq// там довольно нетривиально внутри всё происходило, "как не в одном потоке". если я правильно помню.при чём здесь потоки? или я не понимаю о каких потоках идёт речь. <> то-то и оно, что вроде-бы не причём. (постгрес нигде ничего не параллелит сам) но код исполнялся в каком то странном порядке, как если бы исполнялся в разных потоках, или над разными перемеными. даже нотисы в неочевидном порядке лезли. в общем найти бы тот топег, где это всё это было с кодом, и с разбором -- было бы интересно сравнить с "диаграммой", взятой с потолка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2014, 13:35:38 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
qwwqкод исполнялся в каком то странном порядке, как если бы исполнялся в разных потокахразные потоки и разные транзакции - это в моём понимании разные вещи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2014, 13:57:12 |
|
||
|
Update строки во время удаления, отменяет удаление
|
|||
|---|---|---|---|
|
#18+
roadsterqwwqкод исполнялся в каком то странном порядке, как если бы исполнялся в разных потокахразные потоки и разные транзакции - это в моём понимании разные вещи. и ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.07.2014, 14:06:29 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=38706962&tid=1998554]: |
0ms |
get settings: |
9ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
185ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
| others: | 222ms |
| total: | 512ms |

| 0 / 0 |
