|
|
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
savosin_sergeyэти блокировки много от чего зависят, вряд ли можно обойтись какими-то настройками, вроде autocommit=yes/no.. в msSqlServer2k, например, на них влияет настройка isolation level транзакции, "хинты" в операторах insert, update, select, delete ну и, конечно же, от выбора СУБД тоже многое зависит! так что либо использовать хранимые процедуры, либо писать нормальные триггеры, т.е. управлять транзакциями на СУБД, а не из powerBuilder'а.. Вернемся к теме. Приведите ситуацию, в которой по Вашему мнению нужна явная блокировка: Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 14:11 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
sboykoИдеи конечно правильные - никто не возражает. Но кроме OLTP есть просто информационные системы, в которых блокировка документа является способом указать что с ним уже работают и другие изменения не приветствуются. Вопрос о конкурирующих транзакциях вообще не стоит. Можно поставить TimeStamp, но можно просто блокировать. DeadLock не будет потому работа идет с одной таблицей. Поэтому вопрос и был, что все таки в PowerBuilder позволяет делать явные операции блокировок-получается ничего. вопрос стоял (хоть и в скрытой форме) так "как мне реализовать счётчик записей, удовлетворяющих некоторому условию". Просто я его уже задал на другом форуме, а здесь начал "издалека". 2 всем: Интересно сравнить ответы чистых "серверников" в разделе mssqlserver и "прикладников" в разделе powerBuilder.. ответ ASCRUS (а затем и других) с блокировкой вспомогательной таблицы посредством update table очень помог (хотя и было непонятно сначала, что блокировка update не снимается до commit tran )! только не понятно, чем триггер плох? та же хранимая процедура, хоть и сработает после добавления, но номер проставить всё же можно.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 14:32 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky Вернемся к теме. Приведите ситуацию, в которой по Вашему мнению нужна явная блокировка: Код: plaintext Эта тема была создан всвязи с таким insert 'ом. Но сейчас я думаю, что "хинт" на insert вешать -- не дело. Намного элегантнее всё решить в триггере, блокируя вспомогательную таблицу. Хотя в указанном примере вспомогательная таблица вообще не используется.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 14:37 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
а сама проблема звучит так авторпроблема: в таблице есть поля "первичный ключ", "дебет" и "номер позиции". для некоторых дебетов (капитальные вложения, 106) надо в поле "номер позиции" присваивать последовательные номера (в разрезе всей таблицы) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 14:39 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
savosin_sergeyа сама проблема звучит так авторпроблема: в таблице есть поля "первичный ключ", "дебет" и "номер позиции". для некоторых дебетов (капитальные вложения, 106) надо в поле "номер позиции" присваивать последовательные номера (в разрезе всей таблицы) server side Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. client side Код: plaintext 1. 2. 3. 4. Это работает в любой DBMS без всяких явных блокировок и прочего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 15:58 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
savosin_sergeyИнтересно сравнить ответы чистых "серверников" в разделе mssqlserver и "прикладников" в разделе powerBuilder.. ответ ASCRUS (а затем и других) с блокировкой вспомогательной таблицы посредством update table очень помог И к какому классу Вы относите ASCRUS'а? Кстати, я хотел предложить похожий вариант... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 16:16 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
2 Anatoly Moskovsky авторtable doc ( id identity, debit, pos); table idgen (name, curr_id); trigger on doc after insert or update of debit if new.debit = 106 then update idgen set curr_id = curr_id + 1 where name = 'doc.pos'; select curr_id into :new.pos from idgen where name = 'doc.pos'; end if; end trigger; да, блокировки все сами правильно расставляются первым update'ом, я теперь тоже вкурсе! хотя ваш скрипт немного бы изменил (с учётом того, что в mss в триггере обрабатываются сразу все изменённые/добавленные записи, а не одна.. да и документ надо изменить): (синтаксис ms sql 2000, с теми же таблицами) Код: plaintext 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 16:47 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
Локшин Марк savosin_sergeyИнтересно сравнить ответы чистых "серверников" в разделе mssqlserver и "прикладников" в разделе powerBuilder.. ответ ASCRUS (а затем и других) с блокировкой вспомогательной таблицы посредством update table очень помог И к какому классу Вы относите ASCRUS'а? Кстати, я хотел предложить похожий вариант... это форум можно назвать "прикладным". Прикладывается он к powerbuilder'у ;-). А на msSqlServer-форуме обитают "теоретики" (ничего против не имею!). И решения одной и той же проблемы различаются.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 16:51 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
savosin_sergey Ну во первых вместо: Код: plaintext 1. 2. 3. 4. Код: plaintext 1. 2. 3. 4. Далее - Вы не вняли моему совету сделать все на ХП и все таки влепили в триггер, так что могу смело критиковать: В моем варианте номер получается до операции с таблицей Doc, таким образом мы получаем и блокируем/резервируем свой новый номер для сессии, потом просто вставляем его сразу с записью. В Вашем варианте Вы вставляете запись, потом получаете номер, потом обновляете ту же запись. Это плохой вариант - затягиваем транзакцию, увеличиваем лог, неявно вызываем UPDATE триггера не по делу, не можем на таблицу повесить CHECK ((debit <> '160' and pos is null) or (debit = '160' and pos is not null)). В общем я еще раз настоятельно рекомендую подумать о ХП исключительно из за того, что в качестве РСУБД выступает MSSQL. Была бы та же ASA, где можно прямо в BEFORE TRIGGER инициализировать значение вставляемого/изменяемого поля, я бы там сразу же порекомендовал триггер. авторИ к какому классу Вы относите ASCRUS'а? Ну на данном форуме я исключительно прикладник, на Sybase я исключительно серверник, а к MSSQL слава богу вот уже 2 года никакого отношения не имею :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 17:03 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
ASCRUS savosin_sergey Ну во первых вместо: Код: plaintext 1. 2. 3. 4. Код: plaintext 1. 2. 3. 4. переменная @rc дальше используется в триггере. ASCRUSВ общем я еще раз настоятельно рекомендую подумать о ХП исключительно из за того, что в качестве РСУБД выступает MSSQL. Была бы та же ASA, где можно прямо в BEFORE TRIGGER инициализировать значение вставляемого/изменяемого поля, я бы там сразу же порекомендовал триггер. Подумаю. Правда в msSql2000 появились instead-триггеры ("вместо"), но все примеры использования я видел только для вьюх. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 18:52 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
Я сам не пользовался instead-of триггерами, но читал по форуму MSSQL, что при их использовании возникают различные проблемы. Так что лучше перед их использованием порыться по форуму "на всякий пожарный". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.06.2005, 19:18 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
авторНу на данном форуме я исключительно прикладник, на Sybase я исключительно серверник, а к MSSQL слава богу вот уже 2 года никакого отношения не имею :) Ну что касается обсуждаемого вопроса, то насколько я понимаю, ASE будет себя вести аналогично MS SQL... Это же пельмени, но они же равиоли... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.06.2005, 09:40 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
Локшин Марк авторНу на данном форуме я исключительно прикладник, на Sybase я исключительно серверник, а к MSSQL слава богу вот уже 2 года никакого отношения не имею :) Ну что касается обсуждаемого вопроса, то насколько я понимаю, ASE будет себя вести аналогично MS SQL... Это же пельмени, но они же равиоли... Что то мне кажется, что на ASE эта задача будет еще сложнее решаться - вряд ли там есть instead триггера или же хинты на DML операторы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.06.2005, 10:23 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
ASCRUSЧто то мне кажется, что на ASE эта задача будет еще сложнее решаться - вряд ли там есть instead триггера или же хинты на DML операторы. Так есть же вариант с sp? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.06.2005, 11:27 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
и без instead-триггера можно: ASCRUSтак что могу смело критиковать: В моем варианте номер получается до операции с таблицей Doc, таким образом мы получаем и блокируем/резервируем свой новый номер для сессии, потом просто вставляем его сразу с записью. В Вашем варианте Вы вставляете запись, потом получаете номер, потом обновляете ту же запись. Это плохой вариант - затягиваем транзакцию, увеличиваем лог, неявно вызываем UPDATE триггера не по делу, не можем на таблицу повесить CHECK ((debit <> '160' and pos is null) or (debit = '160' and pos is not null)). В общем я еще раз настоятельно рекомендую подумать о ХП исключительно из за того, что в качестве РСУБД выступает MSSQL. Была бы та же ASA, где можно прямо в BEFORE TRIGGER инициализировать значение вставляемого/изменяемого поля, я бы там сразу же порекомендовал триггер. проверку можно в after-триггер вставить, так как он выполняется в одной транзакции вместе с вызвавшем его insert 'ом. То есть rollback откатит и вставку записей: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. а то, что триггер вызывается после вставки, а не вместо -- ничего не испортит в алгоритме расстановки нумерации. Откатится как счётчик, так и строка в документе, даже если между insert и триггером вклинится другой триггер.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.06.2005, 11:32 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
ASCRUSЭто плохой вариант - затягиваем транзакцию, увеличиваем лог, неявно вызываем UPDATE триггера не по делу по поводу увеличения лога: рассмотрим таблицы (документ, счётчик) и триггер на документ: Код: plaintext 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. сделаем две вставки: вызывающую откат и без отката: (триггер вызывается один раз на каждый insert into doc.. ) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.06.2005, 11:56 |
|
||
|
блокировка таблицы при insert
|
|||
|---|---|---|---|
|
#18+
savosin_sergey Как реализовать генерацию номера dnum ? да с учётом многопользовательского доступа к таблице "документ"? Я виду пока два способа. 1-й способ ..... было предложено при insert блокировать таблицу ( insert into <table> with(TABLOCKX) ). Довольно мрачно, но deadlock'и пропали. 2-й способ ... Возможное решение: наложение блокировки на таблицу счётчиков! чтобы с ней мог работать одновременно только один триггер.. есть ли ещё способы, работающие реализации такого "выборочного" инкремента номера документа? поделитесь! Да есть, без триггеров и явных (ручных) блокировок, на уровне RC: insert into <table> (id, debit, num) values (:id, :debit, GetNextNumOnDebit(debit, 1)); insert into <table> (id, debit, num) values (:id, :debit, GetNextNumOnDebit(debit, 2)); . . . insert into <table> (id, debit, num) values (:id, :debit, GetNextNumOnDebit(debit, 100)); commit; // rollback; /* function double GetNextNumOnDebit(string debit, double num) RPCFUNC ALIAS FOR "~"xxxx~".~"GetNextNumOnDebit~"" */ GetNextNumOnDebit должна быть спроектирова так, чтобы после первого вызова до COMMIT / ROLLBACK, получение значений другими сессиями для этого значения debit, было невозможно. Самый прямолинейный способ - использование вспомогательной таблицы и метода UPDATE ... SET NUM = NUM+NUM_INTERVAL WHERE... с последующим SELECT NUM INTO ... Механизм, тут уже объяснили. При отсутствии желания все делать правильно и красиво, можно и хранимую процедуру заменить на метод объекта или глобальную функцию и все писать на PB (я так не делаю) );. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.06.2005, 18:11 |
|
||
|
|

start [/forum/topic.php?fid=15&msg=33105870&tid=1338308]: |
0ms |
get settings: |
6ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
55ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
38ms |
get tp. blocked users: |
1ms |
| others: | 200ms |
| total: | 322ms |

| 0 / 0 |
