|
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
|
Всё прекрасно проводится в небольших транзакциях и ещё в момент работы с базой других пользователей (правда, последние говорят, что база жутко тормозит).
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |