gifts2017

DBEng32 (7.0.0.3, SEQ) – исправление ошибки “CodeBase –56” при использовании 1SQLite для 1С:Предприятие 7.7

Опубликовал Владимир (hogik) в раздел Администрирование - Системное

Исправление ошибки “CodeBase –56” при использовании 1SQLite (версия 1018f) для 1С:Предприятие 7.7(http://infostart.ru/projects/2127/).
Скачать: http://infostart.ru/profile/2905/projects/2418/
Что делает данная разработка?
Реализована возможность управления использованием методов Begin/EndReadSequence() при выполнении запроса. Если запрос выполняется внутри транзакции, то эти методы исполняются с блокировкой таблиц. Если запрос выполняется вне транзакции, то эти методы не исполняются, даже если они вызываются в 1SQLite. Т.е. если запрос выполняется внутри модуля проведения документа, то эти методы будут исполняться, и запрос будет выполняться быстро. В остальных случаях пользователь может управлять режимом выполнения запроса с помощью функций Начать/Зафиксировать/ОтменитьТранзакцию().
Причины возникновения ошибки.
Для ускорения выполнения запросов в 1SQLitе используется метод BeginReadSequence() штатного движка 1С. Данный метод значительно ускоряет последовательный просмотр таблицы по индексу. Но для этого в штатном движке выполняется блокировка таблицы по записи. Если в другой сессии делается попытка обновления данной таблицы внутри метода EndTransaction(Commit), то проверка освобождения таблицы выполняется в цикле N раз (примерно за одну минуту), после чего выдаётся (!) команда обновления таблицы. И СУБД возвращает этому методу код возврата “-56”. В штатном движке данный код возврата обрабатывается как требование аварийного завершения сессии 1С. Т.к. это происходит в момент записи данных транзакции, то в базе данных может образоваться противоречивая информация.
Пути решения.
1) Использовать разработки, снимающие 100% занятость процессора при ожидании освобождения блокировки. В этих разработках в цикл опроса добавляется функция sleep(). Т.е. суммарное время опроса освобождения таблицы увеличивается и за это время запрос из другой сессии 1С может успеть завершиться. Но может и не успеть. :-(((
2) Использовать разработку “DBEng32 SEQ”. В этой разработке перехватываются методы BeginReadSequence() и EndReadSequence(). И в них добавляются вызовы методов BeginTransaction(), PutTLock(Full) перед выдачей BeginReadSequence(). А после вызова метода EndReadSequence() вызывается EndTransaction(Commit). Таким образом, запрос выполняется в транзакции с попыткой блокировки таблицы, для которой выдан метод BeginReadSequence(). Ожидание освобождения таблицы осуществляется другими алгоритмами, на которые влияет, установленное в настройках 1С “Время ожидания захвата таблицы Базы Данных (сек.)”. И в случае неуспешного ожидания освобождения таблицы сессия 1С не завершается аварийно, а происходит откат транзакции. Очевидным недостатком такого решения является тот факт, что общая производительность системы падает из-за неоправданных ожиданий завершения запроса, не выполняющего обновления данных. Кроме того, могут возникать клинчи. Но порчи базы данных не происходит. Естественно, что такой алгоритм можно перенести из “DBEng32 SEQ” в 1SQLite.
3) Разработать алгоритм “внешней блокировки” таблиц. Общий смысл алгоритма в том, что перед выполнением запроса делается попытка блокировать внешние ресурсы, сопоставленные реальным таблицам базы данных используемым в запросе. Таблицы (внешние ресурсы) блокируются до начала выполнения всего запроса. После выполнения запроса блокировки снимаются. А перед выполнением метода EndTransaction(Commit) осуществляется проверка и ожидание освобождения этих внешних ресурсов. Такой алгоритм позволит избежать клинчей и неоправданного ожидания окончания выполнения запросов в других сессиях. Данный алгоритм можно реализовать с участием “DBEng32 SEQ” или в самой 1SQLite осуществить перехват метода EndTransaction().
4) Отказаться от использования метода BeginReadSequence() в 1SQLite. Но в этом случае скорость выполнения запроса будет сопоставима со скорость выполнения алгоритма выборки данных штатными языковыми средствами 1С.
5) Использовать другие СУБД, свободные от данной проблемы, вместо штатного движка 1С. Например, DBEng32 для Advantage или CodeBase. Но для этого надо обеспечить совместимость 1SQLite c этими разработками.

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Сhe Burashka (CheBurator) 31.07.08 01:42
..блин.. истина где-то рядом...
2. Владимир (hogik) 31.07.08 02:47
3. Евгений Мартыненков (JohnyDeath) 31.07.08 10:56
Ну хорошо, что нашлось решение, а то негоже такому красивому проекту загнутся из-за этой проблемы.
Конечно, лечше чтоб эти правки были сделаны в 1sqlite, а то получается, что вы хотите улучшить 7-ку, а выходит что вы нарушили авторские права, подправив движок 1с
4. Владимир (hogik) 31.07.08 12:25
(3)(JohnyDeath)
“нарушили авторские права, подправив движок 1с”
У меня вопрос не по теме. Под какую формулировку в законе об авторских правах попадают разработки такого рода?
P.S. А ошибка ““CodeBase –56” есть и без использования 1SQLite. Только вероятность её появления очень мала.
5. Евгений Мартыненков (JohnyDeath) 31.07.08 12:30
(4) Ну, на сколько я помню, нельзя каким-либо образом патчить/исправлять файлы программы. Если я не прав - поправьте меня.
6. Аркадий Кучер (Abadonna) 31.07.08 12:39
(5) Мне почему-то кажется, что если я честно купил программу, то лично для себя могу делать с ней, что хочу: хоть запатчить, хоть испортить ;)
7. Евгений Мартыненков (JohnyDeath) 31.07.08 12:48
(6) мне тоже так хочется думать, но, по-моему, законодателям так не кажется.
8. Владимир (hogik) 31.07.08 12:52
(5)(JohnyDeath)
“Если я не прав - поправьте меня”
Не знаю. Я давно хочу это выяснить.
Вот это уже отменили?

Лицо, правомерно владеющее экземпляром программы для ЭВМ, вправе без согласия правообладателя и без выплаты дополнительного вознаграждения декомпилировать или поручать декомпилирование программы для ЭВМ с тем, чтобы изучать кодирование и структуру этой программы при следующих условиях:
информация, необходимая для взаимодействия независимо разработанной данным лицом программы для ЭВМ с другими программами, недоступна из других источников;
информация, полученная в результате этого декомпилирования, может использоваться лишь для организации взаимодействия независимо разработанной данным лицом программы для ЭВМ с другими программами, а не для составления новой программы для ЭВМ, по своему виду существенно схожей с декомпилируемой программой для ЭВМ или для осуществления любого другого действия, нарушающего авторское право;
декомпилирование осуществляется в отношении только тех частей программы для ЭВМ, которые необходимы для организации такого взаимодействия.

http://www.fips.ru/avp/law/3523-1S.HTM
9. kolodina (kolodina) 12.08.08 12:07
думаю, если некто купил программу - то может делать с ней все что хочет... авторские права тут не нарушаются... авторские права нарушаются, если вы купили программу - и выдаете ее за свою...
пропатченный движок я установила на двух станциях - у меня выхода нету... целая подсистема написана с использованием 1sqlite... если его оттуда убрать - тормоза будут несказанные...
10. kolodina (kolodina) 12.08.08 13:19
а вот вопрос - я поставила пропатченный движок на двух станциях - а остальные пока не трогала... могут быть проблемы? спасибо.
11. Владимир (hogik) 12.08.08 14:50
12. Евгений Мартыненков (JohnyDeath) 21.08.08 10:03
Hogik, я вот фразу одну недопонял:
"В остальных случаях пользователь может управлять режимом выполнения запроса с помощью функций Начать/Зафиксировать/ОтменитьТранзакцию()."
надо ли это понимать так:
Если я выполняю запрос вне модуля проведения (например в отчете), то мне необходимо писАть:
Код
НачатьТранзакцию();
Запрос.ВыполнитьЗапрос(ТекстЗапроса);
ЗафиксироватьТранзакцию();
Показать полностью

?
13. Владимир (hogik) 21.08.08 14:23
(12)(JohnyDeath)
“то мне необходимо писАть”
Необходимо, перед тем как “писАть”, принять решение, что важней в конкретном алгоритме – скорость выполнения запроса или ожидание освобождения заблокированной таблицы в других сессиях. Т.е. если запрос выполнять вне транзакции, то он будет выполняться медленно, но в других сессиях не будет возникать ожидания освобождения блокировки таблицы. Если запрос выполнять внутри транзакции, то он будет выполняться быстро, но в других сессиях будет возникать ожидание освобождения таблицы.
14. Евгений Мартыненков (JohnyDeath) 21.08.08 15:33
(13) т.е. я тебя понял правильно и пример для внешнего отчета написал правильно?
и рекомендации сделать в 1sqlite Begin/EndReadSequence() опциональным здесь как раз-таки будет очень кстати?
15. Владимир (hogik) 21.08.08 15:53
(14)(JohnyDeath)
“для внешнего отчета написал правильно?”
На этот вопрос нет однозначного ответа. Правильно будет и то, что Вы написали. И без запуска транзакции тоже будет правильно. Всё зависит от поставленных Вами задач в алгоритме. Или Ваш вопрос ко мне в чем-то другом?
“сделать в 1sqlite Begin/EndReadSequence() опциональным ”
Да. Но, думаю, имеет смысл иметь не два режима – “включено/выключено”, а ещё и, типа, - “авто”. Т.е. внутри транзакции эти методы вместе с блокировкой таблицы имеет смысл выполнять в 99% случаев, т.к. блокировка существует и по другим причинам. И если транзакция уже активизирована по другим причинам, то уж и заодно имеет смысл активизировать Begin/EndReadSequence().
16. Евгений Мартыненков (JohnyDeath) 21.08.08 16:47
(15)Или Ваш вопрос ко мне в чем-то другом?
Я вот что имел ввиду: как бы ты поступил, если бы знал, что этот запрос во внешнем отчете выполняется продолжительное время
17. Владимир (hogik) 21.08.08 17:21
(15)(JohnyDeath)
“как бы ты поступил”
Применительно к 1SQLite я б выяснил:
1) Что означает “продолжительное время”.
2) Используются ли таблицы запроса в других, параллельно выполняющихся, задачах.
3) Сколько времени выполняется данная выборка штатными средствами 1Са.
И т.д. Т.е. опять однозначного ответа не может быть.
А если говорить вообще, то я б постарался построить систему так, чтобы таких вопросов (проблем) не возникало.
P.S. Посмотрите, пожалуйста, сообщения (20), пункт #3 в http://infostart.ru/profile/2905/blogs/482/ Мне очень интересно Ваше мнение по поводу данного “явления”.
18. Владимир (hogik) 21.08.08 17:25
+(17)
Я ошибся. Не пункт #3, а пункт #2.
19. Евгений Мартыненков (JohnyDeath) 21.08.08 17:29
(17) всё-таки, наверное, мы не поняли друг друга (= я плохо изъяснился)
Спрошу по-другому: "Не решает ли этот патч движка проблему автоматически? Т.е. я, как программист 1С, просто напишу
Код
Запрос.Выполнить(ТекстЗапроса)
Показать полностью

а пропатченный движок сам всё разрулит:
1) если он выполняется внутри транзакции (например, в модуле проведения), то он выбирает "быстрый способ"
2) если вне транзакции, то "медленный" (с отключенным ReadSequence)
?
20. Евгений Мартыненков (JohnyDeath) 21.08.08 17:35
21. Владимир (hogik) 21.08.08 17:37
(19)(JohnyDeath)
“проблему автоматически?”
Он это и делает.
22. Владимир (hogik) 21.08.08 17:44
(20)(JohnyDeath)
Прочел Ваш ответ. Суть происходящего мне ясна. Мой вопрос был в другом. Вам это “явление” ничего не напоминает? И как люди работают с этим при наличии такого “явления”?
23. Евгений Мартыненков (JohnyDeath) 21.08.08 17:53
(22) " И как люди работают с этим при наличии такого “явления”?"
Наверное так: пользователей натаскивают на то, что если они видят эту ошибку, ждут чуть-чуть и пробуют ещё ;) ( а вообще лучше у kiruh-и спросить, он Фокс использует очень широко)
(21) “проблему автоматически?”
Он это и делает.

Меня просто смутила фраза из описания: В остальных случаях пользователь может управлять режимом выполнения запроса с помощью функций Начать/Зафиксировать/ОтменитьТранзакцию().
Т.е. я могу "смело" ставить пропатченный движок и не переписывать те места, где я использую 1sqlite?
24. Владимир (hogik) 21.08.08 18:04
(23)(JohnyDeath)
“я могу "смело" ставить пропатченный движок и не переписывать те места, где я использую”
Да. Но учитывать фразу “только для тестирования”… ;-)))
А что касается моего вопроса про “явление”, то, похоже, мне опять не удалось сформулировать вопрос. Но отложим это. Сейчас, думаю, важней разобраться с 1SQLite.
25. Евгений Мартыненков (JohnyDeath) 21.08.08 18:17
(24) Да. Но учитывать фразу “только для тестирования”… ;-)))
именно поэтому я и поставил слово СМЕЛО в кавычки. ;)
26. Сhe Burashka (CheBurator) 11.09.08 01:16
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа