Переключение на Главную Страницу Страницы: 1 2 [3]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Как обойти блокировку таблицы _1SBKTTLC? (число прочтений - 11680 )
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #30 - 07. Октября 2009 :: 17:20
Печать  
chicago писал(а) 07. Октября 2009 :: 16:59:
Z1 писал(а) 07. Октября 2009 :: 13:57:
Все это вполне реально сделать(сложность будет может быть только с УРБД ).


Почему? О УРБД еще не думал.

С ней с УРБД всегда сложности.

Может есть за что зацепиться когда стартует подгрузка УРБД  ?
В этом весь и вопрос.

Сложности с УРБД есть большая вероятность отката всех изменений например документ блокирован кем то.

Далее когда подгружается УРБД то не выполняются модуль проведения ( и модуль отмены проведения документа ).

Если делать чистый 27 то как узнать что самый ранний документ не откатился за период нач константы изменения документов.

Если делать 27+28 то как помещать документы в очередь ?
(ведь модуль проведения не исполняется)

Как возможное из решений перед подгрузкой В sql процеcе подгрузки но уже в транзакции надо выполнить :
1.захватить монопол блокировку на таблицы журнал документов
2.создать (включить) тригер на изменение таблицы журнала документов
3.при срабатывании тригера учитывать 27 и 28

После окончания подгрузки тригер удалить ( или выключить )

Либо вместо всего этого узнавать произошла подгрузка успешно
и самим  анализировать zip файла что же мы подгрузили но
вдруг это не сработает а если 27+28 за время анализа еще попадут другие документы и порядок
очереди будет не такой - что тоже плохо.


  
Наверх
 
IP записан
 
Захар Малиновский
Junior Member
**
Отсутствует


1C++ active user

Сообщений: 53
Местоположение: г. Харьков
Зарегистрирован: 26. Февраля 2009
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #31 - 04. Декабря 2009 :: 11:59
Печать  
classic писал(а) 23. Сентября 2009 :: 10:31:
alexdd писал(а) 23. Сентября 2009 :: 10:14:
Народ, а что это все даст? Это что оптимизация блокировок? Почему тогда _1sbkttl, _1sjourn все равно залочен на все время проведения документа.
Если оптимизация производительности, тоже сомнительно, вместо update - insert в другую таблицу и view, и че от этого будет быстрее?
может я туплю, конечно, но чет нихрена непонимаюУлыбка

Это все имеет смысл, если ты оключишь блокировки в базе.
Тогда если проводятся 2 разные документа - они не будут натыкаться на журнал документов. НО: велика вероятность того, что им обоим придется обновить одинаковые строки в таблицах kttl, kttlc.
Сейчас часто получается так, что эти строки обновляются неверно, одно из одновременных изменений теряется. 10 + 5 + 5 = 15.
В случае же инсертов (я надеюсь) - подобных потерь быть не должно.
По крайней мере - я это дело уже запустил на боевой базе, для проверки. 60000 строк в таблице движений. Полет нормальный, тормозов не замечено.


Если это про расхождение таблиц итогов с суммой по проводкам то вот:
 подобное расхождение таблицы итогов БИ с суммой проводок может быть из-за кода select max(rowid) from 1sentry   в процедуре _1sp__1SENTRY_MaxRowID
Два пользователя могут получить как результат выполнения _1sp__1SENTRY_MaxRowID одинаковые rowid якобы своих новых записей (своих только что сделаных инсертов) в 1sentry.
Т.е. два пользователя все правильно пишут в 1sentry, но один из них меняет итоги по суммам проводок другого пользователя.
Надо код хранимой процедуры _1sp__1SENTRY_MaxRowID менять так чтоб там было READPAST. Пусть игнорируют незаконченные транзакции и считают  RowID _своих_ инсертов в 1sentry максимальным.

  
Наверх
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #32 - 04. Декабря 2009 :: 12:28
Печать  
(Захар Малиновский) Это ты о каком режиме блокировок говоришь ?
О стандартном или о чем то еще ?
  
Наверх
 
IP записан
 
classic
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 330
Местоположение: г. Харьков
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #33 - 04. Декабря 2009 :: 16:19
Печать  
Захар Малиновский Спасибо. Проверю в боевой базе на следующей неделе
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #34 - 04. Декабря 2009 :: 16:46
Печать  
Цитата:
READPAST. Применяется только к оператору SELECT и только к строкам, блокированным с помощью блокировки на уровне строк. Пропускаются строки, блокированные другими транзакциями, которые обычно включаются в набор результатов; возвращает результаты без этих блокированных строк. Может использоваться только с транзакциями, выполняемыми на уровне изолированности read committed.




Если свои блокировки и READPAST
что будет
пусть сейчас есть макс  id = 10
начали первое проведение из comp1
выставили READPAST
получили следущ id = 11

начали второе  проведение из comp2
выставили READPAST
получили следущ id = 11 ( тот же самый !!!)
Закончилось проведение на первом comp1
Закончилось проведение на втором comp2 -
что при этом произойдет точно не знаю либо откатимся по ошибке либо что-то еще ?

Если я ошибаюсь то поправьте меня.


PS
С помощью двух Предупреждение в модулях проведения
легко смоделировать ситуацию
  
Наверх
 
IP записан
 
chicago
Senior Member
****
Отсутствует


1C++, I have nothing to
say more!

Сообщений: 316
Местоположение: Тернополь-Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #35 - 07. Декабря 2009 :: 08:25
Печать  
Процедуру "_1sp__1SENTRY_MaxRowID" можно переписать с:
Код
Выбрать все
set nocount on select @i=MAX(ROW_ID) from _1SENTRY(NOLOCK) if @i is null select @i=0 


на
Код
Выбрать все
set nocount on select @i=@@IDENTITY if @i is null select @i=0 

  
Наверх
ICQ  
IP записан
 
Захар Малиновский
Junior Member
**
Отсутствует


1C++ active user

Сообщений: 53
Местоположение: г. Харьков
Зарегистрирован: 26. Февраля 2009
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #36 - 07. Декабря 2009 :: 11:27
Печать  
chicago писал(а) 07. Декабря 2009 :: 08:25:
Процедуру "_1sp__1SENTRY_MaxRowID" можно переписать с:
Код
Выбрать все
set nocount on select @i=MAX(ROW_ID) from _1SENTRY(NOLOCK) if @i is null select @i=0 


на
Код
Выбрать все
set nocount on select @i=@@IDENTITY if @i is null select @i=0 



Так сделать, это себе вовред.  Я ж говорю - ИТОГИ начнут расходиться с суммой проводок. Несколько (два для простоты) подключений пользователей выполняющих код процедуры _1sp__1SENTRY_MaxRowID   _одновременно_  получат ,в твоём случае, rowid последнего , а НЕ СВОЕГО инсерта проводок.
Это если у тебя не более одного документа  одновременно проводится в системе тогда ты прав. Но ты в теме про отключенные стандартные блокировки 1с.
  
Наверх
IP записан
 
chicago
Senior Member
****
Отсутствует


1C++, I have nothing to
say more!

Сообщений: 316
Местоположение: Тернополь-Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #37 - 07. Декабря 2009 :: 14:03
Печать  
Захар Малиновский писал(а) 07. Декабря 2009 :: 11:27:
chicago писал(а) 07. Декабря 2009 :: 08:25:
Процедуру "_1sp__1SENTRY_MaxRowID" можно переписать с:
Код
Выбрать все
set nocount on select @i=MAX(ROW_ID) from _1SENTRY(NOLOCK) if @i is null select @i=0 


на
Код
Выбрать все
set nocount on select @i=@@IDENTITY if @i is null select @i=0 



Так сделать, это себе вовред.  Я ж говорю - ИТОГИ начнут расходиться с суммой проводок. Несколько (два для простоты) подключений пользователей выполняющих код процедуры _1sp__1SENTRY_MaxRowID   _одновременно_  получат ,в твоём случае, rowid последнего , а НЕ СВОЕГО инсерта проводок.
Это если у тебя не более одного документа  одновременно проводится в системе тогда ты прав. Но ты в теме про отключенные стандартные блокировки 1с.


Дайте пример как можно сделать "себе вовред".

Делаю так:
1. Первая сесия:
Код
Выбрать все
BEGIN TRAN

exec sp_executesql N'Insert into _1SENTRY values( @P1,@P2,...

declare @P1 int
set @P1=0
exec _1sp__1SENTRY_MaxRowID @P1 output
select @P1

--ROLLBACK TRAN 



получаю 412050.

2. Вторая сесия:
Код
Выбрать все
BEGIN TRAN

exec sp_executesql N'Insert into _1SENTRY values( @P1,@P2,...

declare @P1 int
set @P1=0
exec _1sp__1SENTRY_MaxRowID @P1 output
select @P1

--ROLLBACK TRAN 



получаю 412051.

Запись проводок и пересчет итогов идет последовательно:
а).
Код
Выбрать все
exec sp_executesql N'Insert into _1SENTRY values( @P1,@P2,... 


б).
Код
Выбрать все
declare @P1 int
set @P1=0
exec _1sp__1SENTRY_MaxRowID @P1 output
select @P1 


в).
Код
Выбрать все
exec _1sp__1SENTRY_NewEntry... 



Какая вероятность того, что перед пунктом б). сесии №1 "вклинится" пункт а). сесии №2?

Покажите мне как можно сделать так что бы в SQL значение @@IDENTITY получить "НЕ СВОЕГО инсерта" если значения Duration пункта а). в 99% равно 0?

Спасибо.
  
Наверх
ICQ  
IP записан
 
Захар Малиновский
Junior Member
**
Отсутствует


1C++ active user

Сообщений: 53
Местоположение: г. Харьков
Зарегистрирован: 26. Февраля 2009
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #38 - 08. Декабря 2009 :: 13:27
Печать  
Дайте пример как можно сделать "себе вовред".
Запись проводок и пересчет итогов идет последовательно:
а).
Код
Выбрать все
exec sp_executesql N'Insert into _1SENTRY values( @P1,@P2,... 


б).
Код
Выбрать все
declare @P1 int
set @P1=0
exec _1sp__1SENTRY_MaxRowID @P1 output
select @P1 


в).
Код
Выбрать все
exec _1sp__1SENTRY_NewEntry... 



Какая вероятность того, что перед пунктом б). сесии №1 "вклинится" пункт а). сесии №2?

Покажите мне как можно сделать так что бы в SQL значение @@IDENTITY получить "НЕ СВОЕГО инсерта" если значения Duration пункта а). в 99% равно 0?

Спасибо.
[/quote]

Всё дело просто в том что между  а) и пунктом б)  есть  какой-то алгоритм. Т.е. какойто call , ret и еще много чего что может удлиннять промежуток времени между ИНСЕРТОМ и вызовом _1sp__1SENTRY_MaxRowID. А плюс много-задачность на терминальном сервере, приостановка процессов планировщиком.   Вопрос "А какая вероятность что ..." - ну не знаю. _Большая_ вероятность. Ибо такое у меня было.  
Два инсерта в одну и туже таблицу из двух сессий могут быть. и они могут выполниться подряд на скл сервере.
  
Наверх
IP записан
 
Захар Малиновский
Junior Member
**
Отсутствует


1C++ active user

Сообщений: 53
Местоположение: г. Харьков
Зарегистрирован: 26. Февраля 2009
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #39 - 08. Декабря 2009 :: 13:35
Печать  
Chicago, ты в своем примере все сделал в одном пакете (batch).
"
exec sp_executesql N'Insert into _1SENTRY values( @P1,@P2,...
declare @P1 int
set @P1=0
exec _1sp__1SENTRY_MaxRowID @P1 output
select @P1
"
Один batch sql сервер может и не разрывает  операторами из других сессий. Точно не знаю.
На практике же 1с эти две строки отправляет не сервер разными batch.
  
Наверх
IP записан
 
Захар Малиновский
Junior Member
**
Отсутствует


1C++ active user

Сообщений: 53
Местоположение: г. Харьков
Зарегистрирован: 26. Февраля 2009
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #40 - 08. Декабря 2009 :: 13:54
Печать  
Z1 писал(а) 04. Декабря 2009 :: 16:46:
[quote]READPAST. Применяется только к оператору SELECT и только к строкам, блокированным с помощью блокировки на уровне строк. Пропускаются строки, блокированные другими транзакциями, которые обычно включаются в набор результатов; возвращает результаты без этих блокированных строк. Может использоваться только с транзакциями, выполняемыми на уровне изолированности read committed.


Z1, парня с надписью "God member" как то боязно расстраивать Улыбка  , но твой пример я не понял.
Тут надо понять особенность отправки на сервер инсерта в 1entry и  последующего exec __1sp__1sentry_MaxRowID.
Они отправляються на сервер так что между ними сервер скл может вставить операторы других сессий.
Поєтому предлагаеться __1sp__1sentry_MaxRowID приказывать не брать во внимание (т.е. READPAST) сделанные инсерты другими сессиями (пока эти ДРУГИЕ сессии не скажут COMMIT). А ихний COMMIT будет позже нашего select max(rowid) from _1sentry (READPAST) _почти_ точно. А почти это потому что вдруг какой - то код , которого в 1с по стандарту нет, сделает инсерт и СРАЗУ commit. Вот тогда , может быть, нас не спасает READPAST. Но у меня такого нет.


  
Наверх
IP записан
 
chicago
Senior Member
****
Отсутствует


1C++, I have nothing to
say more!

Сообщений: 316
Местоположение: Тернополь-Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как обойти блокировку таблицы _1SBKTTLC?
Ответ #41 - 08. Декабря 2009 :: 14:41
Печать  
Захар Малиновский писал(а) 08. Декабря 2009 :: 13:35:
ты в своем примере все сделал в одном пакете (batch).
"
exec sp_executesql N'Insert into _1SENTRY values( @P1,@P2,...
declare @P1 int
set @P1=0
exec _1sp__1SENTRY_MaxRowID @P1 output
select @P1
"
Один batch sql сервер может и не разрывает  операторами из других сессий. Точно не знаю.
На практике же 1с эти две строки отправляет не сервер разными batch.


Да, в одном пакете.

Покажите мне в профайлере пример (доказательство) когда "на практике же 1с эти две строки отправляет не сервер разными batch" конструкции "Операция.Записать()".

Как мы можем утверждать о большой вероятности того что мы сами не можем сэмулировать экспериментально?
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1 2 [3] 
ОтправитьПечать