07.10.2019, 13:33 | #21 |
Участник
|
Цитата:
Есть еще много частных случаев - например в случае остатков, они не меняются при обработке документа, вместо этого создается лог изменений и по событию окончания транзакции этот лог записывается в основную таблицу. Вот еще несколько частных случаев - https://denistrunin.com/understanding-sql-blocking Последний раз редактировалось trud; 07.10.2019 в 13:36. |
|
07.10.2019, 14:29 | #22 |
Участник
|
Цитата:
Сообщение от trud
В READ COMMITED SNAPSHOT блокировок вообще нет. т.е. в общем случае предполагается что если у вас 2 сессии меняют одно и тоже, то у вас что-то не в порядке с бизнес процессами и одна из сессий при попытке сохранения записи получит сообщение о ошибке - "Запись изменена другим пользователем, обновите форму".
Есть еще много частных случаев - например в случае остатков, они не меняются при обработке документа, вместо этого создается лог изменений и по событию окончания транзакции этот лог записывается в основную таблицу. Вот еще несколько частных случаев - https://denistrunin.com/understanding-sql-blocking |
|
07.10.2019, 14:36 | #23 |
Участник
|
Не понял фразы "некорректный показатель". Возможно надо обсудить пример.
Но вся система на этом построена, проблемы с некорректностью чего-то я даже и не припомню. Repeatable Read будет блокировать сессии, АХ так не работает |
|
07.10.2019, 18:08 | #24 |
Участник
|
Цитата:
x = select quantity from balance where productid = 5; update balance set quantity = x+2 where productid = 5; Без RR у вас количество может неправильное записаться, если между первой и второй командой влезет транзакция, которая изменит quantity. Называется non-repeatable read. https://en.wikipedia.org/wiki/Isolat...peatable_reads |
|
07.10.2019, 18:22 | #25 |
Участник
|
Если коротко, то в Аксапте есть
1. пессимистическая модель обновления (используется редко) когда блокировка ставится в момент выборки на select и тогда никто не вклинится в вашем примере а повиснет в блокировке. 2. оптимистическая модель обновления (это основной случай) когда блокировка ставится только в момент обновления. Тогда ваши опасения обоснованы. Но в Аксапте для этого есть защита. в каждой записи есть поле RecVersion которое меняется при каждом обновлении на другое псевдослучайное значение. И аксапта при выполнении обновления проверяет сохранилось ли это значение на момент обновления таким же как было при выборке, если не сохранилось значит кто-то другой уже влез (то чего вы боитесь) и тогда ядро аксапты выбрасывает исключение "конфликт обновления записей" и либо идет обработка этой ситуации программистом X++ либо идет откат транзакции. Это все работает внутри открытой транзакции в режиме Read committed |
|
07.10.2019, 18:24 | #26 |
Участник
|
Ну с RR вы получите блокировку, это как-бы не очень хорошо.
АХ по дефолту при update balance set quantity = x+2 where productid = 5; вернет вам ошибку, если запись уже кто-то обновил в другой сессии. Для этого в любой таблице добавляется столбец RecVersion, который рандомно заполняется при обновлениях, и если кто-то обновил запись до вас, у нее будет другое значение RecVersion. но это если не касаться остатков если говорить о остатках, то вместо update balance set quantity = x+2 where productid = 5; будет выполнено insert balanceLog(qty=2, productid = 5) и далее на завершении транзакции этот лог перепишется в таблицу балансов |
|
07.10.2019, 22:59 | #27 |
Участник
|
Вот пример джоба по работе с разными типами блокировок
X++: static void example(Args _args) { #define.RetryNum(5) void test( ConcurrencyModel _concurrencyModel = ConcurrencyModel::Auto, boolean _readPast = false) { InventTable inventTable; ; try { ttsbegin; inventTable.concurrencyModel(_concurrencyModel); if (_readPast) { inventTable.readPast(_readPast); } select forceliterals inventTable where inventTable.ItemId == "0000001"; inventTable.NameAlias += "1"; inventTable.doupdate(); ttscommit; } catch (exception::UpdateConflict) { if (appl.ttsLevel() == 0) { if (xSession::currentRetryCount() >= #RetryNum) { throw Exception::UpdateConflictNotRecovered; } else { retry; } } else { throw Exception::UpdateConflict; } } } ; test(ConcurrencyModel::Optimistic); test(ConcurrencyModel::Pessimistic); } X++: SELECT A.ITEMID, ... A.RECVERSION,A.RECID FROM INVENTTABLE A WHERE ((DATAAREAID=N'MRC') AND (ITEMID=N'0000001')) X++: UPDATE INVENTTABLE SET NAMEALIAS=?,RECVERSION=?,MODIFIEDDATE=?,MODIFIEDTIME=?,MODIFIEDBY=?
WHERE (((DATAAREAID=?) AND (RECID=?)) AND (RECVERSION=?)) для случая пессимистичной модели будут такие запросы: X++: SELECT A.ITEMID, ... A.RECVERSION,A.RECID FROM INVENTTABLE A WITH( UPDLOCK) WHERE ((DATAAREAID=N'MRC') AND (ITEMID=N'0000001')) X++: UPDATE INVENTTABLE SET NAMEALIAS=?,RECVERSION=?,MODIFIEDDATE=?,MODIFIEDTIME=?,MODIFIEDBY=?
WHERE ((DATAAREAID=?) AND (RECID=?)) Все запросы работают в READ COMMITTED В случае оптимистической модели вероятность блокировок значительно ниже. Проверено на практике. Последний раз редактировалось Logger; 07.10.2019 в 23:07. |
|
07.10.2019, 23:13 | #28 |
Участник
|
Logger, trud. Я может чего-то не понимаю, но ведь это же повторение логики версионников. Зачем это Axapta делает, если можно просто включить Serializable и СУБД в версионном режиме, и СУБД сама кинет update conflict?
|
|
07.10.2019, 23:22 | #29 |
Участник
|
Затрудняюсь ответить.
Нужно спрашивать тех кто проектировал ядро. Возможно это делалось для SQL 2000, т.е. для тех случаев когда БД не поддерживает какие-то режимы. Но это только мое предположение. Когда это проектировали, аксапта еще поддерживала Оракл. Возможно это сказалось. |
|
08.10.2019, 00:26 | #30 |
Banned
|
Извините, что встреваю в эту дискуссию, но вы ведете подсчет ангелов на острие иглы. Была сегодня попытка устроить продажу потенциальному клиенту в соседнем селе. Это, как обычно просветляет. Вопросы, которые интересовали собственника предприятия:
1) Сколько стоит 2) Сколько людей нужно нанять, чтобы обслуживать систему 3) Что он за это получит Другими словами: Функциональные возможности и их Стоимость. Вопросы блокировок его не интересовали. |
|
08.10.2019, 12:03 | #31 |
Участник
|
Цитата:
А эти вопросы напрямую влияют на масштабируемость системы, на стоимость поддержки и доработок. Тем более что клиент платит не один раз а постоянно. Ну а, вообще, мне, например, интересен взгляд квалифицированного специалиста со стороны. |
|
08.10.2019, 12:29 | #32 |
Участник
|
Цитата:
Сообщение от EVGL
Извините, что встреваю в эту дискуссию, но вы ведете подсчет ангелов на острие иглы. Была сегодня попытка устроить продажу потенциальному клиенту в соседнем селе. Это, как обычно просветляет. Вопросы, которые интересовали собственника предприятия:
1) Сколько стоит 2) Сколько людей нужно нанять, чтобы обслуживать систему 3) Что он за это получит Другими словами: Функциональные возможности и их Стоимость. Вопросы блокировок его не интересовали. И вот когда ты будешь переворачивать логику так как хочет заказчик и всплывают блокировки и все остальное. |
|
|
За это сообщение автора поблагодарили: George Nordic (5). |
08.10.2019, 12:30 | #33 |
Участник
|
Цитата:
|
|
08.10.2019, 12:33 | #34 |
Участник
|
|
|
08.10.2019, 14:11 | #35 |
Участник
|
Цитата:
Цитата:
SERIALIZABLE
Specifies the following: Statements cannot read data that has been modified but not yet committed by other transactions. |
|
08.10.2019, 14:38 | #36 |
Moderator
|
Цитата:
Просто я сам не пробовал (и вполне возможно что я в этом вопросе не прав), но кто-то из знакомых SQL разработчиков мне рассказывал что в этом режиме тоже есть свои подводные грабли. Вот например в статье описывают поведение системы при проверке целостности Foreign Keys, и как-то это не очень очевидно. |
|
08.10.2019, 17:47 | #37 |
Участник
|
Цитата:
Сообщение от trud
АХ сделано так чтобы блокировок не было, в случае SERIALIZABLE они будут (это вообще самый строгий тип блокировок)
Доп столбец RecVersion в любой таблице как раз и был добавлен чтобы поддерживать READ_COMMITTED_SNAPSHOT(ON). Я кстати не очень понимаю как можно сделать по другому, в любом другом варианте(т.е. используя UPDATE) вы упретесь что SQL Server не поддерживает блокировку по строкам |
|
08.10.2019, 17:57 | #38 |
Участник
|
Цитата:
Сообщение от fed
А вы пробовали стандартным функционалом update conflict в MS SQL пользоваться ?
Просто я сам не пробовал (и вполне возможно что я в этом вопросе не прав), но кто-то из знакомых SQL разработчиков мне рассказывал что в этом режиме тоже есть свои подводные грабли. Вот например в статье описывают поведение системы при проверке целостности Foreign Keys, и как-то это не очень очевидно. Foreign keys правда не пользовался (и непонятно зачем в MS SQL вдруг озаботились этой проблемой, когда Write Skew все равно есть, но видимо решили частный случай один поддержать). |
|
09.10.2019, 00:52 | #39 |
Участник
|
Цитата:
https://docs.microsoft.com/en-us/sql...ql-server-2017 Цитата:
REPEATABLE READ
Specifies that statements cannot read data that has been modified but not yet committed by other transactions and that no other transactions can modify data that has been read by the current transaction until the current transaction completes. |
|
|
За это сообщение автора поблагодарили: Logger (3). |
09.10.2019, 08:26 | #40 |
Участник
|
NitroJunkie, а чего цитировать документацию?
Есть же запросы. Запускаем , проверяем блокировки. Времени на это надо 1 минуту. |
|