Как правильно читать из базы 1С на MSSQL напрямую? Или блокировки при select

shatalov
Дата: 11.02.2010 17:54:47
При выполнении селектов к базе 1С на Microsoft SQL Server 2000 - 8.00.2039 (Intel X86) пользователи 1С жалуются на большие ожидания при сохранении документов в 1С.
База MS-SQL прилинкована через ODBC к Oracle. Запросы выполняются в Oracle.
Источник ODBC создан как ReadOnly.
В MS-SQL был создан пользователь, ему выданы права для базы 1С "public" и "db_datareader".
Сами запросы по времени выполнения занимают не более 1 секунды.
Мониторил блокировки через sp_lock в OA. Обычно на сессию одна блокировка "S" на базу.
Но один раз словил 10402 строки на эту читающую сессию.
spid	dbid	ObjId	IndId	Type	Resource		Mode	Status
92	9	0	0	DB	                	S	GRANT
92	2	3	2	KEY	(710158e1fcd6)  	X	GRANT
92	2	0	0	IDX	IDX: 2:939735742	X	GRANT
92	2	3	2	KEY	(1702a0f9f999)  	X	GRANT
92	2	939735742	0	TAB	                Sch-M	GRANT
92	2	3	2	KEY	(670150912f83)  	X	GRANT
92	2	2	1	KEY	(530090131264)  	X	GRANT
92	2	3	2	KEY	(bc0105efd4a4)  	X	GRANT
92	2	0	0	EXT	1:864           	X	GRANT
92	2	99	0	RID	1:865:0         	X	GRANT
92	2	3	2	KEY	(6802c47f424d)  	X	GRANT
92	2	3	2	KEY	(15021398a27a)  	X	GRANT
92	2	3	1	KEY	(8e00487bb48f)  	X	GRANT
92	2	3	2	KEY	(9802054d7b69)  	X	GRANT
92	2	0	0	PAG	1:880           	X	GRANT
92	2	3	2	KEY	(bb02ef89755e)  	X	GRANT
и так далее

Вопросы
1. Откуда растут ноги у этих блокировок?
2. Являются они причиной долгих сохранений в 1С?
3. Как с ними бороться?
- после каждого select делать comnit?
- после каждого select разрывать соединение с MS-SQL?
4. Как правильно читать данные из MS-SQL без блокировок?
5. Или просто, что я делаю не правильно?

Спасибо.
pkarklin
Дата: 11.02.2010 17:58:18
автор
1. Откуда растут ноги у этих блокировок?


2000 - чистый блокировочник, и поэтому даже при чтении накладывает S (разделяемые блокировки).

автор
4. Как правильно читать данные из MS-SQL без блокировок?


Хинт NOLOCK. Но учтите, что читаете еще не закомиченные данные.
pkarklin
Дата: 11.02.2010 17:59:50
В догонку...

автор
Но один раз словил 10402 строки на эту читающую сессию.


Это не только читающая сессия, раз есть X и Sch-M блокировки.
Glory
Дата: 11.02.2010 18:01:10
1. Из запроса, который выполняется
2. Если другие коннекты ожидают снятия этих блокировок, то являются
3. select и так снимает все блокировки после окончания. Если только вы специально на выстроили транзакцию с удержаниями блокировок
И бороться надо не с блокировками, а с их продолжительностью и излишеством
4. Если вас не интересует правильность данных, то используйте NOLOCK
5. Непонятно, что вы вообще делаете
shatalov
Дата: 11.02.2010 18:20:16
Спасибо за ответы.

Glory

5. Непонятно, что вы вообще делаете


В программе (не 1С), работающей с БД на Oracle, нужно по запросу пользователя получить документ из 1С. Для этого в Oracle создан DB Link на MSSQL через шлюз ODBC. Программа генерирует два запроса.
SELECT j.DOCNO,
       SUBSTR(j.DATE_TIME_IDDOC,7,2)||'.'||SUBSTR(j.DATE_TIME_IDDOC,5,2)
          ||'.'||SUBSTR(j.DATE_TIME_IDDOC,1,4) DATE_SCH,
       j.IDDOC, k.DESCR KontrAg
FROM "_1SJOURN"@MS1CSYS j, DH2457@MS1CSYS z, SC172@MS1CSYS k
WHERE IDDOCDEF=2457 AND SKL_STRNUM_COMP(DOCNO,:NumStr)<>0
       AND z.IDDOC=j.IDDOC AND k.ID=z.SP2434
ORDER BY DATE_TIME_IDDOC DESC
SELECT dt.LINENO_, ns.SP85 Articul, ns.DESCR, dt.SP2447 Kolvo, e.EZ_NAME, 
            n.NAME, n.ID
FROM DT2457@MS1CSYS dt, SC84@MS1CSYS ns, PL_NOMENK n, PL_EDIZM e
WHERE ns.ID=dt.SP2446 AND n.ARTICUL(+)=ns.SP85 AND e.ID(+)=n.EDIZM_ID 
           AND dt.IDDOC='  3J3L   '
ORDER BY dt.LINENO_
Но эти запросы выполняются Oracle, который их преобразует в запросы к MSSQL.
Поэтому использовать хинт NOLOCK не получится.
Гавриленко Сергей Алексеевич
Дата: 11.02.2010 18:21:52
shatalov
Спасибо за ответы.

Glory

5. Непонятно, что вы вообще делаете


В программе (не 1С), работающей с БД на Oracle, нужно по запросу пользователя получить документ из 1С. Для этого в Oracle создан DB Link на MSSQL через шлюз ODBC. Программа генерирует два запроса.
SELECT j.DOCNO,
       SUBSTR(j.DATE_TIME_IDDOC,7,2)||'.'||SUBSTR(j.DATE_TIME_IDDOC,5,2)
          ||'.'||SUBSTR(j.DATE_TIME_IDDOC,1,4) DATE_SCH,
       j.IDDOC, k.DESCR KontrAg
FROM "_1SJOURN"@MS1CSYS j, DH2457@MS1CSYS z, SC172@MS1CSYS k
WHERE IDDOCDEF=2457 AND SKL_STRNUM_COMP(DOCNO,:NumStr)<>0
       AND z.IDDOC=j.IDDOC AND k.ID=z.SP2434
ORDER BY DATE_TIME_IDDOC DESC
SELECT dt.LINENO_, ns.SP85 Articul, ns.DESCR, dt.SP2447 Kolvo, e.EZ_NAME, 
            n.NAME, n.ID
FROM DT2457@MS1CSYS dt, SC84@MS1CSYS ns, PL_NOMENK n, PL_EDIZM e
WHERE ns.ID=dt.SP2446 AND n.ARTICUL(+)=ns.SP85 AND e.ID(+)=n.EDIZM_ID 
           AND dt.IDDOC='  3J3L   '
ORDER BY dt.LINENO_
Но эти запросы выполняются Oracle, который их преобразует в запросы к MSSQL.
Поэтому использовать хинт NOLOCK не получится.
И при чем здесь тогда MSSQL?
shatalov
Дата: 11.02.2010 18:29:19
Гавриленко Сергей Алексеевич
И при чем здесь тогда MSSQL?

Проблема в блокировках в MSSQL.
Вопрос как сделать, что бы сессия из оракла по умолчанию была NOLOCK?
Как начать транзакцию с чтением "грязных" данных? Можно ли настроить MSSQL так, что бы у определенного юзера все транзакции были NOLOCK?
Гавриленко Сергей Алексеевич
Дата: 11.02.2010 18:30:10
shatalov
Гавриленко Сергей Алексеевич
И при чем здесь тогда MSSQL?

Проблема в блокировках в MSSQL.
Вопрос как сделать, что бы сессия из оракла по умолчанию была NOLOCK?
Как начать транзакцию с чтением "грязных" данных? Можно ли настроить MSSQL так, что бы у определенного юзера все транзакции были NOLOCK?
Для этого есть вполне определенные конструкции, и сервер совершенно не виноват в том, что оракл их выполнить не может.
shatalov
Дата: 11.02.2010 18:37:18
Может быть, но я не знаю что это за конструкции.
Прошу помощи хотя бы в определении этих конструкций.
Если они обязательны для выполнения из под сессии юзера, может быть потом я придумаю как их выполнить из под оракла.
Но может быть существуют административные "конструкции" применимые для юзера или сессии.

P.S. Я ни в чем не виню сервер MSSQL.