Имя: Пароль:
1C
1C 7.7
v7: Как определить, активна ли транзакция
,
0 rt0107
 
18.08.11
11:37
Собственно, сабж. База DBF.
И вообще, если Док.Провести() возвращает нуль, транзакция остается активной?
1 OnCheck
 
18.08.11
11:38
а про какую транзакцию речь? автоматическую при проведении документа или пользовательскую НачатьТранзакцию()?
2 Ёпрст
 
18.08.11
11:43
(0) нет
3 rt0107
 
18.08.11
11:46
(2) а не типовых способов нету случаем? Скажем, у FormEx или 1C++ ничего такого не наблюдалось? Вроде бы в доках рылся внимательно, но мало ли что.
4 FN
 
18.08.11
11:48
(3) проблемку полностью опиши - может чего дельного и насоветуем...
5 rt0107
 
18.08.11
12:00
Ищу адекватный способ разбить большую транзакцию на ряд более мелких: проводится достаточно большой пак документов, при возможных ошибках неохота перепроводить все с самого начала. Нарисовал так:

Функция СчетчикПлюс(пСчетчик)
   пСчетчик = пСчетчик + 1;
   Если пСчетчик % 10 = 0 Тогда
       ЗафиксироватьТранзакцию();
       НачатьТранзакцию();
   КонецЕсли;
КонецФункции

Функция ПровестиДокумент(пДок, пСчетчик=0)
   Попытка
       й = пДок.Провести();
       Если й = 0 Тогда Возврат 0; КонецЕсли;
   Исключение
       Возврат 0;
   КонецПопытки;
   СчетчикПлюс(пСчетчик);
   Возврат 1;
КонецФункции

и основная процедура выглядит так

   НачатьТранзакцию();
   счДвиженийТранзакции = 0;
   рез = 1;
   Пока ... Цикл
       Если ПровестиДокумент(док, счДвиженийТранзакции) = 0 Тогда
           рез = 0;
           Прервать;
       КонецЕсли;
   КонецЦикла;
   Если рез = 0 Тогда
       ОтменитьТранзакцию();
   Иначе
       ЗафиксироватьТранзакцию();
   КонецЕсли;

Из приведенного кода выкинул для краткости всякие "сообщить" и прочую обвеску.
Так вот, на ЗафиксироватьТранзакцию() в функции СчетчикПлюс() оно падает с воплем "Транзакция не активна".
Причем в первом же паке, когда счетчик до 10 доезжает.
6 FN
 
18.08.11
12:04
Функция ПровестиДокумент(пДок, пСчетчик=0)
   Попытка
       й = пДок.Провести();
       Если й = 0 Тогда Возврат 0; КонецЕсли;
СчетчикПлюс(пСчетчик);
   Исключение
       Возврат 0;
   КонецПопытки;
 
   Возврат 1;
КонецФункции
7 FN
 
18.08.11
12:06
(6)+ это "грубо"...

а вообще фиксируй/отменяй транзакцию в самом цикле, а не в функциях
8 FN
 
18.08.11
12:09
Вот самый простой пример

НачатьТранзакцию();
   сч=0;
   Пока Док.ПолучитьДокумент()=1 Цикл
       Если Док.Провести()=0 тогда
           Сообщить();
           ОтменитьТранзакцию();
           Прервать;
       КонецЕсли;
       сч=сч+1;
       Если сч%100=0 Тогда
           ЗафиксироватьТранзакцию();
           НачатьТранзакцию();
       КонецЕсли;
   КонецЦикла;
   ЗафиксироватьТранзакцию();
9 Ёпрст
 
18.08.11
12:12
(5) так делать категорически не верно.
Будет полная каша в проводках/движениях регистра.

Так что, весь код в топку смело.
10 Ёпрст
 
18.08.11
12:13
При активной транзакции, из базы всегда будут считываться старые движения документов, и толку от такого проведения - нуль.
11 rt0107
 
18.08.11
12:13
(6) не вижу разницы от исходного варианта, ведь если что не так - до СчетчикПлюс() все равно не докатится - на Возврат() наступит.

(7) хотелось избавиться от проверки счетчика, общая обработка достаточно сложна. А в чем грубость в выносе повторяющегося кода в отдельную функцию?

(8) Док.Провести() может трапнуться, и его палюбасу нужно в Попытку оборачивать. Тоже повод для выноса кода в отдельную функцию.

(10) А как верно? Вообще от транзакций отказаться? А как работает штатное восстановление границы последовательности?
12 Ёпрст
 
18.08.11
12:15
(11) Которое в меню Операции ? Там ТА сдвигается назад и всё проведение в потоке идёт.
13 Ёпрст
 
18.08.11
12:15
+12 каждый док толкает ТА вперёд.
14 rt0107
 
18.08.11
12:21
(13) Но ведь согласись, что при восстановлении ГП в базу запись изменений проходит не сразу, нечто вроде транзакций используется. Иначе оно б не выполнялось с такой скоростью.
Опять-таки, я там не слишком вкурил, в каком порядке штатное восстановление ГП документы выбирает для проведения, оно нифига не согласуется с позицией документа.

А вот (10) сейчас проверю.
15 FN
 
18.08.11
12:22
(10) а если в модуле проведения отстатки тянутся прямым запросом - тоже такой глюк?
16 rt0107
 
18.08.11
12:29
(10)

Процедура Сформировать()
   НачатьТранзакцию();
   р = СоздатьОбъект("Регистр.Заявки");
   р.ВыбратьДвижения();
   докДвижения = р.ТекущийДокумент();
   Сообщить("Получено движение "+докДвижения);
   
   док = СоздатьОбъект("Документ");
   док.НайтиДокумент(докДвижения);
   док.УдалитьСтроки();
   док.Записать();
   док.Провести();
   
   Если р.ВыбратьДвиженияДокумента(докДвижения) = 1 Тогда
       Сообщить("Движения сохранились - тест провален");
   Иначе
       Сообщить("Движений нет - тест выборки в транзакции успешен");
   КонецЕсли;
   
   ОтменитьТранзакцию();
КонецПроцедуры

рапортует

   Получено движение Заявка покупателя 0000000292 (21.02.07)
   Движений нет - тест выборки в транзакции успешен

что я не так делаю?
17 Ёпрст
 
18.08.11
12:30
(14) кешируются некоторые данные. Но не всё.
18 FN
 
18.08.11
12:31
(10) Что-то ты путаешь.
Сделал эксперимент:
На складе есть 50 шт товара.
Делаю два не проведенных расходных документа по 30 шт, провожу их в одной транзакции и на втором документе срабатывает контроль остатков.
ЧЯДНТ?
19 Ёпрст
 
18.08.11
12:46
Лень проверять, но транзакция - зло.
20 rt0107
 
18.08.11
12:48
(19) Классный аргумент, позитивный. Даже настроение поднялось. И черт с ней, с производительностью. Согласен.
21 Ёпрст
 
18.08.11
12:50
(20) Какая в п..ду производительность при коде в (0) ?
Ты вообще о чем ?
22 Ёпрст
 
18.08.11
12:52
Быстрее чем через меню операции  - не сделаешь, у тебя всегда проведение задним числом при коде в (0), ===> всегда временный расчет регистров, заместо того, чтоб сразу брать актуальные итоги.
23 rt0107
 
18.08.11
12:56
(21) Окей, пусть там криво и вообще неправильно. Как правильно и быстро перепровести пакет документов при том, что все перепроводить не нужно, а лишь часть?
Например: в сегодняшнем конкретном случае требовалось в ТиС перепровести все заявки на склад, по которым были остатки по регистру резервов. Сделал, отказавшись от транзакций, но интерес к теме есть и на будущее. Расставить документы по дате, и перед проведением каждого документа гонять ТА?
24 Ёпрст
 
18.08.11
13:02
(23) создать нужную последовательность, перепровести её
25 FN
 
18.08.11
13:02
(23) да все правильно. так и надо перепроводить небольшими транзакциями. Просто ты где-то что-то напутал в коде.

Упрости код до (8) и проверь
26 Torquader
 
18.08.11
16:28
Всё прекрасно проводится в небольших транзакциях и ещё в момент работы с базой других пользователей (правда, последние говорят, что база жутко тормозит).