Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Изоляция таблицы
|
|||
|---|---|---|---|
|
#18+
ASA 9.0.2.3221 Вопрос в следующем: есть достаточно большая таблица остатков из которой идет расход и в которую идет приход одновременно (несколько рабочих машин) расход, приход идет через процедуры. и там и там идет выборка из остатков, их изменение и затем вставка данных в другие таблицы. как обеспечить неизменность данных в остатах если работает одна из процедур? в общем чтобы одномоментно работала ТОЛЬКО одна из процедур на сервере? вероятность конечно практически нулевая что одномоментно будут списываться один и тот же товар, но все же... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2006, 15:07 |
|
||
|
Изоляция таблицы
|
|||
|---|---|---|---|
|
#18+
Такие вещи обеспечиваются уровнями изоляций транзакций. Почитать что это такое можно здесь и здесь . Так же неплохо почитать в BOL по секции FROM по хинтам выборочной установки уровней изоляций на таблицы, реализуемый ключевым словом WITH (уровень изоляции). -- www.rusug.ru - портал русскоязычной группы пользователей Sybase ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2006, 15:34 |
|
||
|
Изоляция таблицы
|
|||
|---|---|---|---|
|
#18+
БОЛЬШОЕ спасибо, прочитав вроде бы разобрался. CREATE TABLE "DBA"."test" ( "ID" integer NOT NULL DEFAULT autoincrement, "Value" integer NULL, PRIMARY KEY ( "ID" )); select * from Test ID,Value 1, 1 2, 2 3, 2 4, 3 CREATE PROCEDURE "DBA"."testisolation"() BEGIN select ID into #Tmp from Test with(REPEATABLEREAD) where Value=2; Update Test set Value=9 where Test.ID in (select ID from #TMP); END Правильно ли я понял, что данные в таблице Test НЕ БУДУТ ИЗМЕНЕНЫ другим юзером до тех пор пока их не изменит и не отработает процедура testisolation? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2006, 16:28 |
|
||
|
Изоляция таблицы
|
|||
|---|---|---|---|
|
#18+
Да - но не все данные Test, а только попадающие под условие Value=2, то есть до момента завершения транзакции (COMMIT или ROLLBACK) в таблице Test окажутся заблокированными от изменения записи с кодом 2 и 3. Однако есть еще пара важных моментов, которые стоит обязательно помнить: 1. Так как в процедуре нет оператора завершения транзакции, то например после ее выполнения в том же ISQL данные будут блокированы далее до тех пор, пока сессия не соизволит сказать COMMIT, ROLLBACK или отсоединится (что будет означать ROLLBACK). 2. Всегда стоит разделять shared и exclusive блокироки. Так в процедуре через SELECT мы вешаем shared блокировки, таким образом блокируя писателей на эти записи, но не мешая читателям их читать, а проводя обновление UPDATE мы вешаем exclusive блокировки, таким образом запрещая доступ к данным записям как писателям, так и читателям. 3. Всегда стоит помнить про фантомы, что очень актуально при расчете остатков. Например посредством REPETABLEREAD мы гарантировали, что обрабатываемые записи никем не могут быть изменены. Однако ... если по логике задачи в таблицу разрешаются вставки в таблицу, то здесь этот уровень изоляции не подойдет. Наглядный пример - пока выполняется SELECT в процедуре, другой сессией вставляется и коммитится новая запись с Value2 = 2. Таким образом она не будет учтена в процедуре и в задаче расчетов остатков это приведет к тому, что остаток будет несоотвествовать записям в таблице. Именно по этому, для таких критических вещей уже требуется высший уровень изоляции SERIALIZABLE, который гарантирует не только защиту от изменений существующих записей, но и что никто не добавит новые записи, которые могли бы попасть под условия фильтра необходимых для обработки данных, то есть появлению фантомов. Здесь конечно чтобы не просела производительность параллейной работы множества сессий, будет необходимо тщательно продумать всю логику работы в соответствие с рекомендациями, которые я привел в тех статьях. P.S. А вообще уровни изоляций и блокировки эта сила и скорость ... если только уметь их правильно готовить, понимать как это работает и где и как этим пользоваться, ну и использовать весь набор сапера-блокировочника - по назначению времянки, timestamp поля и прочее ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2006, 17:07 |
|
||
|
Изоляция таблицы
|
|||
|---|---|---|---|
|
#18+
Спасибо еще раз, разжевано и проглочено. Но тут встают два вопроса: если таблица с остатками достаточно большая (не менее 100 000 записей, структура не более 10 полей, РК-глобал аутоинк, условие отбора-по двум полям типа инт. на "=", возможно создание индекса по этим двум полям) то не будет ли быстрее залочить всю таблицу чем лочить строки? насколько я понимаю здесь ответ чисто практический, кто с чем работал. и второе, надо ли обернуть основной этап в процедуре в begin transaction-commit для отсечения только вставленных данных? я так понимаю что да, иначе остальные будут висеть до тех пор(касательно изменений остатка), пока сервер не аутокоммитнется? P.S. 2 уровень изоляции меня вполне устраивает, так как он обеспечит мне изменение ТОЛЬКО существующих записей, без обработки только втавленных и ли являющихся фантомами. (поддерживается причинно-следсвенная зависимость: сначала надо внести в остатки а затем уже списывать, а не начать списывать в ожидании внесения http://www.sql.ru/forum/images/happy.gif) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.06.2006, 17:37 |
|
||
|
|

start [/forum/topic.php?fid=55&msg=33788247&tid=2012788]: |
0ms |
get settings: |
9ms |
get forum list: |
19ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
81ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
52ms |
get tp. blocked users: |
2ms |
| others: | 243ms |
| total: | 426ms |

| 0 / 0 |
