Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Очень популярная тема (более 25 ответов) Блокировка базы SQL в модуле проведения (число прочтений - 7022 )
DimaN
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 10
Зарегистрирован: 31. Января 2010
Блокировка базы SQL в модуле проведения
31. Января 2010 :: 11:16
Печать  
добрый день!
Кто-нибудь сталкивался с такой проблемой:
имеется конфгурация ТиС, 1С 7.7 , база крутится на MS SQL 2000.
Каждый год нужно переходить на новый год, т.е. копируется полностью база и удаляется оттуда журнал, все таблицы очищаются DH/DT xxx , очищается блокнот и периодические константы - это все делается напрямую через SQL Query Analyzer.
Затем через внешнюю форму (ert), переносятся остатки из старой базы в новую.  
В итоге получается новая база, с остатками прошлого года. Все контрагенты и номенклатура остаются нетронутыми.
Проблема заключается в следующем: в модуле проведения документа (расходная накладная) есть прямой запрос к базе SQL через ADO. В старой базе запрос нормально выполняется и проведение документа функционирует так, как положено.
В новой базе при попытке выполнить запрос (CMD.Execute()) вылетает ошибка OLE DB Время ожидания истекло. т.е. процесс не может получить доступ к базе, т.к. она заблокирована (мои предположения).
Если в строке подключения указать старую базу, то запрос выполнится.
Если просто скопировать старую базу, назвать ее по другому и запустить проведение документа, то все работает.
Стоит только выполнить хоть один запрос SQL в Query Analyzer для очистки данных (truncate table _1sjourn), то опять проведение документа не проходит. (срабатывает блокировка базы).
Как можно решить данную проблему?
Предприятие это так работает(меняет базы каждый НГ) на протяжении нескольких лет. Я у них работаю полгода. Звонил предыдущему админу, он не знает в чем причина. Говорит, что все нормально работало.
  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Блокировка базы SQL в модуле проведения
Ответ #1 - 31. Января 2010 :: 12:10
Печать  
Посмотри в профайлере, что может тормозить процесс проведения.
  
Наверх
 
IP записан
 
DimaN
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 10
Зарегистрирован: 31. Января 2010
Re: Блокировка базы SQL в модуле проведения
Ответ #2 - 31. Января 2010 :: 12:52
Печать  
chessman писал(а) 31. Января 2010 :: 12:10:
Посмотри в профайлере, что может тормозить процесс проведения.

а в каком "профайлере" ?
дело не в торможении процесса проведения (как я думаю), а в блокировке какой-то. В старой базе эта же обработка выполняется быстро. А в новой после очистки таблиц (truncate table) не работает.
  
Наверх
 
IP записан
 
chessman
God Member
*****
Отсутствует



Сообщений: 1084
Зарегистрирован: 10. Августа 2007
Re: Блокировка базы SQL в модуле проведения
Ответ #3 - 31. Января 2010 :: 13:17
Печать  
Тормозит, в смысле "зависает". Посмотри, какая команда при этом отправлена на сервер.
  

Clipboard02_007.jpg ( 25 KB | Загрузки )
Clipboard02_007.jpg
Наверх
 
IP записан
 
DimaN
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 10
Зарегистрирован: 31. Января 2010
Re: Блокировка базы SQL в модуле проведения
Ответ #4 - 31. Января 2010 :: 14:35
Печать  
Посмотрел, зависает на первом SELECTE'e, после первого INSERT'a.
вот сам код хранимой процедуры, которую я пытаюсь выполнить.
Код
Выбрать все
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

ALTER     PROCEDURE RestByDocs
	  @Клиент char(9),
	  @ТА char(8) ='0'	  --если передаётся - учитываем гарантии и просрочку
AS
SET NOCOUNT ON
CREATE TABLE #ПриходыРасходы (
	  [DATE_TIME_IDDOC] [char] (23) NOT NULL,
	  [IDDOCDEF] [int]  NOT NULL,
	  [DEBKRED] [bit] NOT NULL ,
	  [SUMM] [numeric](14, 5) NOT NULL
)
CREATE TABLE #Расходы (
	  [DATE_TIME_IDDOC] [char] (23) NOT NULL,
	  [IDDOCDEF] [int]  NOT NULL,
	  [REST] [numeric](14, 5) NOT NULL DEFAULT 0
	  CONSTRAINT [PK_Расходы] PRIMARY KEY  CLUSTERED
	  (
	     [DATE_TIME_IDDOC]
	  )
)

INSERT INTO #ПриходыРасходы (DATE_TIME_IDDOC, IDDOCDEF, DEBKRED, SUMM)
SELECT ЗаВычетомВозвратов.DATE_TIME_IDDOC, ЗаВычетомВозвратов.IDDOCDEF, ЗаВычетомВозвратов.Приход, SUM(ЗаВычетомВозвратов.Сумма)
FROM
(
SELECT     _1S_L_ОбщийЖурнал.DATE_TIME_IDDOC, _1S_L_ОбщийЖурнал.IDDOCDEF, _1S_L_РегВзаиморасчетыПокупателей_Дв.DEBKRED AS Приход,
			    SUM(_1S_L_РегВзаиморасчетыПокупателей_Дв.Долг) AS Сумма
FROM	   _1S_L_ОбщийЖурнал INNER JOIN
			    _1S_L_РегВзаиморасчетыПокупателей_Дв ON _1S_L_ОбщийЖурнал.IDDOC = _1S_L_РегВзаиморасчетыПокупателей_Дв.IDDOC
WHERE     (_1S_L_РегВзаиморасчетыПокупателей_Дв.Клиент = '  1A' + @Клиент) AND (NOT (_1S_L_РегВзаиморасчетыПокупателей_Дв.IDDOC IN
				  (SELECT     _1S_L_ДокПриходнаяНакладная.IDDOC
				    FROM	    _1S_L_РегВзаиморасчетыПокупателей_Дв INNER JOIN
								   _1S_L_ДокПриходнаяНакладная ON
								   _1S_L_РегВзаиморасчетыПокупателей_Дв.IDDOC = _1S_L_ДокПриходнаяНакладная.IDDOC
				    WHERE	(_1S_L_ДокПриходнаяНакладная.ДокументОснование <> '   0     0   ') AND
								   (_1S_L_РегВзаиморасчетыПокупателей_Дв.Клиент = '  1A' + @Клиент)
				    GROUP BY _1S_L_ДокПриходнаяНакладная.IDDOC, _1S_L_ДокПриходнаяНакладная.ДокументОснование)))
GROUP BY _1S_L_ОбщийЖурнал.DATE_TIME_IDDOC, _1S_L_ОбщийЖурнал.IDDOCDEF, _1S_L_РегВзаиморасчетыПокупателей_Дв.DEBKRED

UNION ALL

SELECT     _1S_L_ОбщийЖурнал.DATE_TIME_IDDOC, _1S_L_ОбщийЖурнал.IDDOCDEF, 1- _1S_L_РегВзаиморасчетыПокупателей_Дв.DEBKRED AS Приход,
			     - SUM(_1S_L_РегВзаиморасчетыПокупателей_Дв.Долг) AS Сумма
FROM	   _1S_L_РегВзаиморасчетыПокупателей_Дв INNER JOIN
			    _1S_L_ДокПриходнаяНакладная ON _1S_L_РегВзаиморасчетыПокупателей_Дв.IDDOC = _1S_L_ДокПриходнаяНакладная.IDDOC INNER JOIN
			    _1S_L_ОбщийЖурнал ON _1S_L_ДокПриходнаяНакладная.ДокументОснование = '  BE' + _1S_L_ОбщийЖурнал.IDDOC
WHERE     (_1S_L_РегВзаиморасчетыПокупателей_Дв.Клиент = '  1A' + @Клиент)
GROUP BY _1S_L_ОбщийЖурнал.DATE_TIME_IDDOC, _1S_L_ОбщийЖурнал.IDDOCDEF, _1S_L_РегВзаиморасчетыПокупателей_Дв.DEBKRED,
			    _1S_L_ДокПриходнаяНакладная.ДокументОснование
) AS ЗаВычетомВозвратов
GROUP BY ЗаВычетомВозвратов.DATE_TIME_IDDOC, ЗаВычетомВозвратов.IDDOCDEF, ЗаВычетомВозвратов.Приход

UNION ALL

SELECT     _1S_L_ОбщийЖурнал.DATE_TIME_IDDOC, _1S_L_ОбщийЖурнал.IDDOCDEF, _1S_L_РегВзаиморасчетыПоставщиков_Дв.DEBKRED AS Приход,
			    SUM(_1S_L_РегВзаиморасчетыПоставщиков_Дв.Долг) AS Сумма
FROM	   _1S_L_РегВзаиморасчетыПоставщиков_Дв INNER JOIN
			    _1S_L_ОбщийЖурнал ON _1S_L_РегВзаиморасчетыПоставщиков_Дв.IDDOC = _1S_L_ОбщийЖурнал.IDDOC
WHERE     (_1S_L_РегВзаиморасчетыПоставщиков_Дв.Клиент = @Клиент)
GROUP BY _1S_L_ОбщийЖурнал.DATE_TIME_IDDOC, _1S_L_ОбщийЖурнал.IDDOCDEF, _1S_L_РегВзаиморасчетыПоставщиков_Дв.DEBKRED


if @ТА<>'0'
    INSERT INTO #ПриходыРасходы (DATE_TIME_IDDOC, IDDOCDEF, DEBKRED, SUMM)
	  SELECT     _1S_L_ОбщийЖурнал.DATE_TIME_IDDOC,_1S_L_ОбщийЖурнал.IDDOCDEF, 1 AS Приход,
		    SUM((1 - _1S_L_РегГарантииОплат_Дв.DEBKRED * 2) * _1S_L_РегГарантииОплат_Дв.Наличность) AS Сумма
	  FROM	   _1S_L_ОбщийЖурнал INNER JOIN
			    _1S_L_РегГарантииОплат_Дв ON _1S_L_ОбщийЖурнал.IDDOC = _1S_L_РегГарантииОплат_Дв.IDDOC
	  WHERE     (_1S_L_РегГарантииОплат_Дв.Клиент = @Клиент)
	  GROUP BY _1S_L_ОбщийЖурнал.DATE_TIME_IDDOC, _1S_L_ОбщийЖурнал.IDDOCDEF, _1S_L_РегГарантииОплат_Дв.DEBKRED

DECLARE @d_k bit, @s numeric(14, 5), @rst numeric(14, 5)

INSERT INTO #Расходы (DATE_TIME_IDDOC, IDDOCDEF, REST)
SELECT DATE_TIME_IDDOC, IDDOCDEF, SUMM FROM #ПриходыРасходы
WHERE DEBKRED = 0

DECLARE ПоРасходам CURSOR FOR
SELECT REST FROM #Расходы WHERE REST <> 0
order by DATE_TIME_IDDOC
FOR UPDATE OF REST

DECLARE @sp numeric(14, 5)

SELECT @sp=sum(SUMM) FROM #ПриходыРасходы WHERE DEBKRED = 1
set @sp=isnull(@sp,0)

OPEN ПоРасходам
FETCH NEXT FROM ПоРасходам INTO @rst
WHILE @@FETCH_STATUS = 0
BEGIN
	  IF @sp >= @rst
	  BEGIN
		    SET @sp = @sp - @rst
		    UPDATE #Расходы
		    SET REST = 0
		    WHERE CURRENT OF ПоРасходам
	  END
	  ELSE
	  BEGIN
		    UPDATE #Расходы
		    SET REST = REST - @sp
		    WHERE CURRENT OF ПоРасходам
		    SET @sp = 0
	  END

	  IF @sp = 0 BREAK
  


весь код не влезает. В старой базе всё выполняется отлично, а также все работает, если я эту базу скопирую и буду в запросе из 1С подключаться к копии, тогда тоже работает.
  
Наверх
 
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Блокировка базы SQL в модуле проведения
Ответ #5 - 31. Января 2010 :: 19:02
Печать  
Ну значит та база, к которой подключаешься, открыта в монопольном режиме. При этом другие подключения невозможны. Если же ты делаешь запросы к текущей базе при помощи прямых запросов, то по АДО в монопольном режиме - не получится, так как создается другой коннект к базе. От этой проблемы свободна 1С++, т.к. в ней запросы идут через "родной" коннект.
  
Наверх
ICQ  
IP записан
 
DimaN
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 10
Зарегистрирован: 31. Января 2010
Re: Блокировка базы SQL в модуле проведения
Ответ #6 - 01. Февраля 2010 :: 00:38
Печать  
Salimbek писал(а) 31. Января 2010 :: 19:02:
Ну значит та база, к которой подключаешься, открыта в монопольном режиме. При этом другие подключения невозможны. Если же ты делаешь запросы к текущей базе при помощи прямых запросов, то по АДО в монопольном режиме - не получится, так как создается другой коннект к базе. От этой проблемы свободна 1С++, т.к. в ней запросы идут через "родной" коннект.

в том-то и дело, что я захожу не через монопольный режим.
Такая же обработка, через ADO, стоит во внешнем отчете и без проблем выполняется. А из модуля проведения не хочет.
Подозрение у меня на очистку таблиц функцией truncate table, может она какие-то параметры меняет?
я уже весь в ступоре, не знаю куда смотреть...
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Блокировка базы SQL в модуле проведения
Ответ #7 - 01. Февраля 2010 :: 06:12
Печать  
Лучше опиши задачу в обычный терминах.
Также не понятно при переходе на новую базу очищаются ли
ra rg.
Сколько конектов в базе ?
ado для текущей или другой базы ?
Какой размер базы до перехода на новую базу и после перехода
на новую базу ?
  
Наверх
 
IP записан
 
slider26
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 256
Зарегистрирован: 01. Июня 2006
Re: Блокировка базы SQL в модуле проведения
Ответ #8 - 01. Февраля 2010 :: 08:48
Печать  
DimaN писал(а) 01. Февраля 2010 :: 00:38:
в том-то и дело, что я захожу не через монопольный режим.
Такая же обработка, через ADO, стоит во внешнем отчете и без проблем выполняется. А из модуля проведения не хочет.
Подозрение у меня на очистку таблиц функцией truncate table, может она какие-то параметры меняет?
я уже весь в ступоре, не знаю куда смотреть...

Проверь на всякий случай галочку в ЭнтМенеджере для данной базы на закладке ACESS.
Может установилось Restrict acess->Single user?
Т.е. доступ только для одного SQL-пользователя?
Да и просто 2-мя сеансами 1С к базе с удаленной табличкой подключится попробуй...
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Блокировка базы SQL в модуле проведения
Ответ #9 - 01. Февраля 2010 :: 09:28
Печать  
а какой CommandTimeout стоит? Попробуй поставить 0 и в другом соединении посмотреть блокировки(sp_lock).
  
Наверх
 
IP записан
 
DimaN
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 10
Зарегистрирован: 31. Января 2010
Re: Блокировка базы SQL в модуле проведения
Ответ #10 - 01. Февраля 2010 :: 17:13
Печать  
Z1 писал(а) 01. Февраля 2010 :: 06:12:
Лучше опиши задачу в обычный терминах.
Также не понятно при переходе на новую базу очищаются ли
ra rg.
Сколько конектов в базе ?
ado для текущей или другой базы ?
Какой размер базы до перехода на новую базу и после перехода
на новую базу ?

Задача в следующем: при проведении расходной накладной необходимо проверить Клиента на его задолженность. Для определения задолженности написана хранимая процедура в базе, которая в параметрах получает ИмяКлиента и ДатуТА. Если у клиента есть задолженность, то документ не проводится.
При переходе на новую базу Ra,Rg не очищаются. Скрипт очистки писал не я, не понял почему так.
К базе примерно 15 коннектов.
ADO для текущей базы.
Размер базы одинаковый практически (примерно 1Гб)

Если эту же обработку оформить как Внешний Отчет, то все работает и соединяется. Тут проблема именно с модулем проведения либо с какими-то полями/параметрами базы.
  
Наверх
 
IP записан
 
DimaN
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 10
Зарегистрирован: 31. Января 2010
Re: Блокировка базы SQL в модуле проведения
Ответ #11 - 01. Февраля 2010 :: 17:14
Печать  
slider26 писал(а) 01. Февраля 2010 :: 08:48:
Проверь на всякий случай галочку в ЭнтМенеджере для данной базы на закладке ACESS.
Может установилось Restrict acess->Single user?
Т.е. доступ только для одного SQL-пользователя?
Да и просто 2-мя сеансами 1С к базе с удаленной табличкой подключится попробуй...

Галочки этой не стоит, к базе без проблем подключаются 15 человек.
  
Наверх
 
IP записан
 
DimaN
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 10
Зарегистрирован: 31. Января 2010
Re: Блокировка базы SQL в модуле проведения
Ответ #12 - 01. Февраля 2010 :: 18:00
Печать  
alexdd писал(а) 01. Февраля 2010 :: 09:28:
а какой CommandTimeout стоит? Попробуй поставить 0 и в другом соединении посмотреть блокировки(sp_lock).

CommandTimeout  стоит по умолчанию. Я его не задавал.
Попробовал поставить 0.
В профайлере поставить следить за LOCK'ами.
вот что вышло: при начале выполения процедуры замок захватывается 3 раза, потом освобождается 2 раза, потом опять захватывается 3-4 раза, потом освобождается 3-4 раза и так далее.
lock:Accured - lock.Released
И все в таком духе. Где-то восле 20ти таких циклов вывалился Exception: Error: 208, Severity: 16, State: 0. и дальше пошли циклы захвата и освобождения замка.
Это все в Profiler.
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Блокировка базы SQL в модуле проведения
Ответ #13 - 01. Февраля 2010 :: 18:21
Печать  
Error 208?
Цитата:
Invalid object name '%.*ls'.

Ну тогда, насколько я могу судить, ошибка где-то в логике процедуры. Не хватает ей какого-то объекта.
Кстати, по-умолчанию, CommandTimeout=30 сек. То есть процедура выполняется дольше 30 секунд, при 0 выполняется пока не выполнится.
  
Наверх
 
IP записан
 
DimaN
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 10
Зарегистрирован: 31. Января 2010
Re: Блокировка базы SQL в модуле проведения
Ответ #14 - 01. Февраля 2010 :: 18:37
Печать  
alexdd писал(а) 01. Февраля 2010 :: 18:21:
Error 208?
Цитата:
Invalid object name '%.*ls'.

Ну тогда, насколько я могу судить, ошибка где-то в логике процедуры. Не хватает ей какого-то объекта.
Кстати, по-умолчанию, CommandTimeout=30 сек. То есть процедура выполняется дольше 30 секунд, при 0 выполняется пока не выполнится.

прцедура на старой базе выполняется 2-3 секунды. А то и быстрее.
А эта ошибка вылетела сразу же на первой секунде выполнения.

меня все-равно терзают сомнения насчет truncate table .
Если хоть одну таблицу очистить так, то работать перестает. Видать какой-то параметр изменяется. И именно параметр блокировок. Т.к. вне модуля проведения хранимка выпоняется на ура через ADO.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать