|
v7: "ОтменитьПроведение()" и транзакция... | ☑ | ||
---|---|---|---|---|
0
Zhuravlik
27.10.11
✎
16:48
|
Здравствуйте. В моей базе большой документооборот, кто-то все время что-то перепроводит, в общем транзакции - обычное явление.
Если в обработке мне нужно создать документ, я пользуюсь такой конструкцией: Процедура ВОбходТранзакций(Док, Действие) Попытка Если Действие = "Записать" Тогда Док.Записать(); ИначеЕсли Действие = "Провести" Тогда Док.Провести(); КонецЕсли; Исключение //здесь процедурка с таймаутом... ВОбходТранзакций(Док, Действие) КонецПопытки; КонецПроцедуры //... Док = СоздатьОбъект("Документ.Реализация"); //... ВОбходТранзакций(Док, "Провести"); //... Если в качестве действия задавать Провести, Записать, Новый, ПометкаУдаления - Все прекрасно работает, если во время выполнения началась транзакция, процедура рекурсивно после таймаута вызывается, и дело движется. И только один пункт ломает весь кайф - это если надо отменить проведение документа. Если во время отмены проведения началась транзакция, то ОписаниеОшибки() выдает "ДокументЗаблокирован", причем его нельзя открыть. Как будто он открыт другим пользователем. И чтобы продолжить с этим доком работать надо перезапустить 1С. Иначе он будет заблокирован. Вопрос: Можно ли как-то это обойти? Кроме установки ожидания захвата таблиц в 999, тут есть выносная база, из которой 2-3 раза в день загружаются данные с транзакцией, хаотично. Выгрузка длится 10-15 мин. В общем, не вариант. |
|||
1
Zhuravlik
27.10.11
✎
16:50
|
+ Блокировка(0) тоже не помогает.
|
|||
2
filh
27.10.11
✎
16:54
|
ну как вариант, записывай и если удачно, то отменяй проведение.
|
|||
3
andrewks
27.10.11
✎
16:58
|
"Если во время отмены проведения началась транзакция"
это как? оно и так в транзакции выполняется |
|||
4
Zhuravlik
27.10.11
✎
17:06
|
(3) Знал, что кто-нибудь мимо этого высказывания не пройдет) Я сам толком не понимаю, но получается что отмена проведения не вызывает транзакции. Если бы вызывала, то моя процедурка тут работала, верно?
(2) Нет, хочу 100% вариант. Если бы Записать() возвращала флаг, что документ записан, как в провести() тогда можно было бы... Можно нагородить функцию, типа Функция Записать(док) Попытка док.Записать(); Возврат 1; Исключение записать(док); конецПопытки; КонецФункции Но не хочется городить, если только это единственно возможный вариант... |
|||
5
filh
27.10.11
✎
17:12
|
зачем так сложно
Процедура ВОбходТранзакций(Док, Действие) Попытка Если Действие = "Отменить" Тогда ВОбходТранзакций(Док, "Записать") Док.ОтменитьПроведение(); КонецЕсли; Исключение //здесь процедурка с таймаутом... ВОбходТранзакций(Док, Действие) КонецПопытки; КонецПроцедуры |
|||
6
andrewks
27.10.11
✎
17:13
|
делаю примерно так
КолвоПоп=3; Для СчПоп=1 По КолвоПоп Цикл Попытка //тут делаем свои грязные дела Прервать; Исключение // неудача Если СчПоп<КолвоПоп Тогда Предупреждение("Не удалось создать документ, попытка будет повторена через 5 сек.",5); ИначеЕсли СчПоп=КолвоПоп Тогда Сообщить("Не удалось создать документ","!"); КонецЕсли; КонецПопытки КонецЦикла; |
|||
7
Zhuravlik
27.10.11
✎
17:15
|
(5) через секунду сам до этого дошел)
(6) Да у меня примерно то же самое, просто у вас КолвоПоп, а у меня рекурсия на процедуру. Но если док попадает на транзакцию, то дальнейшая рекурсия просто вываливает ошибку, что документ заблокирован, и капут( |
|||
8
filh
27.10.11
✎
17:16
|
даже если потом транзакция отпускается?
|
|||
9
Zhuravlik
27.10.11
✎
17:17
|
(8) вот именно...
|
|||
10
andrewks
27.10.11
✎
17:17
|
(7) 2. нифига подобного. у тебя нагромождение попыток получается, а у меня одна.
+ немаловажный фактор - правильный sleep |
|||
11
filh
27.10.11
✎
17:19
|
(10) а как попытка влияет на транзакцию?
|
|||
12
Zhuravlik
27.10.11
✎
17:20
|
(10) Но док-то все-равно заблокирован. Я могу оборвать рекурсию, просто поставлю
Если Док.Блокировка() = 1 Тогда Возврат; КонецЕсли; Но мне по сути не это надо, а чтобы док распровелся. А он не распроведется, пока я базу не перезапущу. |
|||
13
Zhuravlik
27.10.11
✎
17:20
|
(11) Никак. Она просто передает управление на исключение, а там таймаут и рекурсия.
|
|||
14
andrewks
27.10.11
✎
17:21
|
(11) теоретически никак. кстати, совсем упустил одну тоже немаловажную деталь - время ожидания захвата у меня установлено в ноль. а вот это уже точно влияет
|
|||
15
КонецЦикла
27.10.11
✎
17:21
|
Нужно ускорять проведение документов и избегать коллапса (как вариант использовать ВК от romix)
Мне в свое время удалось почти уйти от блокировок (при этом кол-во пользователей удвоилось и документостроки выросли) |
|||
16
Zhuravlik
27.10.11
✎
17:23
|
(11) Это влияеть на время выполнения может быть, но у меня в данном случае цель - это отменить проведение дока. А только на времени ожидания (высоком?) я не хочу выезжать, тут это не катит. Надо как-то отловить момент конца транзакции..
|
|||
17
andrewks
27.10.11
✎
17:25
|
(16) попробуй всё-таки время ожидания захвата поставить в ноль у того юзера, под которым обормотка крутится, + делай правильную паузу между попытками, через sleep, или как у меня, через Предупреждение
|
|||
18
filh
27.10.11
✎
17:26
|
(17) лучше Предупреждение.
|
|||
19
andrewks
27.10.11
✎
17:26
|
(18) а чем sleep хуже?
|
|||
20
КонецЦикла
27.10.11
✎
17:28
|
(16) >>Надо как-то отловить момент конца транзакции..
Если не хочешь понимать (15) есть еще вариант проведения всех документов от имени одного пользователя |
|||
21
filh
27.10.11
✎
17:29
|
(19) можно нажать и продолжить
:) |
|||
22
Zhuravlik
27.10.11
✎
17:30
|
(17) я так пробовал, у меня время ожидания в ноль. Это значит, что действие не будет ожидать конца транзакции, вот и все. Проблема остается. Паузу я делаю так:
_с = 0; СекЖдать = 5; Пока СекЖдать>0 Цикл ТекущееВремя(ч,м,с); Состояние(" ТаймАут - "+СекЖдать); Если с<>_с Тогда СекЖдать=СекЖдать-1; _с=с; КонецЕсли; КонецЦикла; |
|||
23
filh
27.10.11
✎
17:31
|
уууу, у тебя загрузка проца же будет идти...
|
|||
24
andrewks
27.10.11
✎
17:33
|
(21) если загрузка роботом - кому оно надо? :)
|
|||
25
andrewks
27.10.11
✎
17:34
|
(22) вот поэтому и вылетает
|
|||
26
filh
27.10.11
✎
17:36
|
(24) бывают же моменты, когда ручками запускаем и смотрим :)
Оба метода хороши. |
|||
27
Zhuravlik
28.10.11
✎
09:38
|
(25) Только что протестил в копии. Не из-за этого. Поставил такую обработку ожидания -
Процедура Пауза(мс=1000) //пауза в милисекундах Если ФС.СуществуетФайл(КаталогПользователя()+"sleep.js")=0 Тогда Текст=СоздатьОбъект("Текст"); Текст.ДобавитьСтроку("WScript.Sleep (250);"); Текст.Записать(КаталогПользователя()+"sleep.js"); КонецЕсли; WshShell=СоздатьОбъект("WScript.Shell"); Тек=_GetPerformanceCounter()+мс; Пока Тек>_GetPerformanceCounter() Цикл WshShell.Run("cscript "+КаталогПользователя()+"sleep.js", 0,-1); КонецЦикла; КонецПроцедуры (взято с инфостарта http://infostart.ru/public/18698/) Запустил двух пользователей. Под одним стал делать тотальную отмену проведения документов, из другой запустил перепроведение доков через стандартную обработку документов. Объект заблокирован. |
|||
28
andrewks
28.10.11
✎
09:41
|
(27) ну а время ожидания захвата в ноль поставил, или нет?
|
|||
29
Zhuravlik
28.10.11
✎
10:07
|
(28) Да. Оно и так стоит в 0 у меня постоянно.
|
|||
30
Zhuravlik
28.10.11
✎
10:21
|
(21) не роботом. бухи загружают каждый день документы из одной базы в другую, - это то, что я пишу. Плюс есть еще выносная база заявок, оттуда тоже с транзакцией 2-3 раза в день выгружаются в доки.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |