Имя: Пароль:
1C
 
Блокировки MS SQL vs SELTA-PostgreSQL
0 WhiteNoise
 
10.04.09
15:41
Здравствуйте.
Хотел затать такой вопрос.
Предыстория:
работаю с PostgreSQL через SELTA@etersoft.
1с при проведении лочит используемые таблицы намертво:
например так:
{call _1sp__1SJOURN_TLockX}
_1SJOURN(TABLOCKX HOLDLOCK)
Но в MS SQL можно все рабно при этом читать таблицы так:
SELECT * FROM _1SJOURN(NOLOCK);

В postgre такого нет(я так понимаю, если есть поправьте меня). В смысле блокировка аналогичная есть(ACCESS EXCLUSIVE), но поле этого таблицу уже не прочитаешь.
Вопросы:
1. Чем мне грозит то, что я сделаю блокировку не такой жесткой, т.е. чтение разрешу. При это только в _1sjourn. Так что никаких отрицательных остатков быть не должно.
2. Что делается с 1с8 при работе с postgres в момент проведения у других пользователей?
1 DmitrO
 
10.04.09
16:02
Незнаю что за зверь SELTA@etersoft, и принципы его работы с базами 77, поэтому мне трудно оценить точно, но на первый взгляд надо во всех блокировочных процедурах 77 использовать блокировку EXCLUSIVE вместо ACCESS EXCLUSIVE. Тогда ACCESS SHARE доступ останется, и будет хоть какое-то подобие грязного чтения применяемого в MSSQL (NOLOCK).
2 WhiteNoise
 
10.04.09
16:56
>SELTA@etersoft,
это и не требуется для ответа на вопрос. Это ms sql->postgre  транслятор
>использовать блокировку EXCLUSIVE вместо ACCESS EXCLUSIVE
Да об этом я и спрашиваю.
>Тогда ACCESS SHARE доступ останется, и будет хоть какое-то подобие грязного чтения применяемого в MSSQL (NOLOCK).
Да, но не будет режима без NOLOCK, что может быть не правильно.
Это будет соответсвовать MS SQL TABLOCK HOLDLOCK, как в функции _1sp__1SJOURN_TLock. Но 1с зачем-то сделал именно две функции.
Что будет, если будет две одинаковых, т.е. обе будут делать TABLOCK HOLDLOCK.
3 DmitrO
 
10.04.09
17:09
Нет, ты не прав.
Процедуры .._TLock (а именно, применяемые в них хинты TABLOCK HOLDLOCK) не обеспечвают эксклюзивную блокировку.
TABLOCK - определяет ширину блокировки, означает что она будет уровня таблицы (не записи, не страницы, а всей таблицы);
HOLDLOCK - определяет длительность блокировки, означает что блокировка должна сохраняться до конца транзакции.
А вот тип блокировки будет - разделяемая, т.е. shared.
Эти процедуры в 77 используются для ЧИСТОГО чтения. Оно происходит, когда идет чтение данных в транзакции.

Поэтому в реализации процедур типа TLock на постгре надо ставить SHARE.
4 DmitrO
 
10.04.09
17:15
++Когда данные читаются вне транзакции в 77, всегда идет грязное чтение (nolock).
Такой принцип работы называется оптимистический параллелизм, это позволяет обеспечить большую производительность базы.
Он позволяет, для примера, запросам формирующим отчеты (они же не в транзакции) не ждать блокировок пользователей, которые в этот момент выполняют изменение данных, но соответственно такие отчеты могут вернуть (и возвращают) нецелостные данные.
5 ДенисЧ
 
10.04.09
17:18
(4) "Когда данные читаются вне транзакции в 77, всегда идет грязное чтение (nolock)."

Это кто такое сказал? О_о
6 DmitrO
 
10.04.09
17:19
Я, а что? Ты мне не веришь?
7 ДенисЧ
 
10.04.09
17:19
(6) Я сильно сомневаюсь в этом.
8 leshikkam
 
10.04.09
17:20
(7) хихи нашел в чьем мнении сомневаться :-)
9 DmitrO
 
10.04.09
17:20
(7) ну со мной тоже бывает, что у меня открываются глаза на вещи, которые я просто обязан был знать, и что?
10 ДенисЧ
 
10.04.09
17:22
(8, 9) ТОлько вот явное указание (нолок) у меня почему-то ускоряло работу.
11 DmitrO
 
10.04.09
17:23
(8) тем не менее, это достойно уважения, добрая половина людей просто промолчат в таком случае.
12 ДенисЧ
 
10.04.09
17:24
(8) Я что, все константы должен помнить? :-))
13 DmitrO
 
10.04.09
17:26
(10) ну правильно, когда ты не указываешь nolock это означает что сервер будет делать чистое чтение, т.е. ставить shred блокировку, которые между собой не конкурируют, но зато конкурируют с exclusive.
А указание nolock не ставит блокировки на данные, а ставит только на схему данных.
14 DmitrO
 
10.04.09
17:27
(13)+ т.е. конкурировать будет только с DDL запросами (изменение структуры таблицы например)
15 DmitrO
 
10.04.09
17:29
(13)++ такое поведение сервера потому, что выставлен такой уровень изоляции по-умолчанию.
16 DmitrO
 
10.04.09
17:35
(12) ты должен, ты один из немногих спецов на этом форуме, который дает дельные советы по SQL.
17 WhiteNoise
 
13.04.09
16:49
Спасибо за ответы, тут есть над чем подумать.
Подумал, к чему пока пришел(с вашей помощью):
(1)TLockX
1.
ms: SELECT * FROM foo(TABLOCKX HOLDLOCK)
Можно заменить на
pg: LOCK TABLE foo IN EXCLUSIVE MODE;
2.
при этом "грязное чтение" можно осущесвить с помощью:
ms: SELECT * FROM foo(NOLOCK)
можно заменить на
pg: SELECT * FROM foo
а "чистое"
ms: SELECT * FROM foo(NOLOCK)
на
pg: SELECT * FROM foo FOR UPDATE;
Поведение при этом получается одинаковое(ну я по крайней мере не нашел отличия).
И это я уже могу сказать не плохо.
(3) TLock
Тогда можно заменить
ms: SELECT * FROM foo(TABLOCK HOLDLOCK)
на
pg: LOCK TABLE foo IN SHARE MODE;
Поведение похоже тоже одинаковое.
Если я где-то не прав, поправьте. И если знаете в чем могут быть отличия.
А в каких случаях 1с приденяет TLock? Я почти всегда вижу TLockX.

PS: (5) Сколько не смотрю на запросы 1c, всегда так.
Еще раз спасибо.
18 DmitrO
 
13.04.09
17:01
ну вроде как все верно..

По поводу где 1С применяет TLock, ну я же писал выше - в транзакциях.
Надо в языке 1С использовать НачатьТранзакцию() сделать запрос (штатный), или выбрать движения регистра, или сделать временный расчет рагистра, ЗафиксироватьТранзакцию(). При этом для объектов базы данных использованных внутри транзакции будут вызваны TLock процедуры.
19 DmitrO
 
13.04.09
17:03
(18)+ таким образом мы гарантированно получим согласованные данные. Это и есть чистое чтение.