|
Cтранное поведение IB
|
|||
---|---|---|---|
#18+
Привет всем. Недавно столкнулся со странным поведением IB, объяснение которому в литературе пока не нашел. Краткое описание задачи: В б/д есть таблица, которая используется в расчете карточки личного счета арендатора для хранения промежуточных данных. Каждый пользователь при подключении получает уникальный номер (GEN_ID(…)), при помощи которого в указанной таблице разделяются записи пользователей. Пред каждым новым расчетом из таблицы удаляются строки, которые использовались данным пользователем в предыдущем расчете. При построении отчета по группе арендаторов производится расчете карточки личного счета и по этим данным подбивается итог, который собственно и попадает в отчет. Все работало нормально, пока в один прекрасный день два пользователя одновременно не запустили на построение эти отчеты, причем с одинаковыми входными параметрами. Распечатав полученные данные они увидели, что итоговые суммы отчетов отличаются. Анализ отчетов показал, что в них отсутствуют некоторые строки, а часть сумм в имеющихся в обоих отчетах строках – значительно отличаются. Причем, вариации с уровнем изоляции транзакции, в которой выполняется отчет, положительного эффекта не дали. Может кто-нибудь знает, в чем загвоздка? Дополнительная информация: ОС Windows 98/2000, IB 6.5, эффект проявляется как в сетевом, так и локальном варианте (на машине с сервером запускал 2-х клиентов). Заранее благодарен, Андрей ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2003, 14:36 |
|
Cтранное поведение IB
|
|||
---|---|---|---|
#18+
Привет! Думаю, стоит почитать про транзакции и уровни изоляции. На Ibase.ru, например. WBR, Alexey ... |
|||
:
Нравится:
Не нравится:
|
|||
13.01.2003, 17:00 |
|
Cтранное поведение IB
|
|||
---|---|---|---|
#18+
А с транзакциями тут сильно и не разгонишься: для моего случая подходят варианты read_committed rec_version и concurrency, использование которых дают одинаковый результат. Единственное отступление от рекомендаций, о котором я знаю – использование большого количества вычислений в одной транзакции. Вчера читал статью Дмитрия Попова в которой нашел следующую информацию: - «На суперах - проблемы с невозможностью распознать сессию пользователя и одновременный расчёт двумя пользователями невозможен. Вариант решения - применение отдельного сервера приложений, который осуществляет запуск подобного расчёта.» Может быть кто-нибудь решал аналогичные проблемы другим способом (кроме использования Linux и IB с архитектурой Classic). ... |
|||
:
Нравится:
Не нравится:
|
|||
14.01.2003, 16:05 |
|
Cтранное поведение IB
|
|||
---|---|---|---|
#18+
Привет! И все же, в данном случае лучше использовать snapshot и все расчеты - с момента начала заполнения временной таблицы до получения результата вести в одной транзакции. В статье Попова речь идет об использовании UDF, которые действительно в Супере совместно используются всеми потоками и последовательный расчет, как в его примере, невозможен. К данному случаю это не имеет отношения, как мне кажется - про UDF ведь ни слова? Варианты граблей - 1)неизолированность транзакций. Все таки, как запускается транзакция? Если снэпшот запустить, и все в рамках _одной_ транзакции делать - то не должно быть интерференций между различными пользователями, в крайнем случае ошибка lock conflict. Вот этот момент прежде всего проверить. 2) неатомарность Select. В рид коммитед длинный Select может видеть данные, которые появились _после_ его старта - и в связи с этим выдавать неправильные результаты, например, Select count(). А если честно, вопрос неясно описан - ни текстов процедур, ни структуры базы. Трудно сказать определенно - ТЛ сломался... WBR, Alexey ... |
|||
:
Нравится:
Не нравится:
|
|||
14.01.2003, 18:43 |
|
Cтранное поведение IB
|
|||
---|---|---|---|
#18+
Alexey Эксперимент проводился следующим образом: запустил 2 IBExpert-а, установил уровень изоляции snapshot и запустил на выполнение процедуру расчета данных для отчета в одном и в другом. Единственное отличие во входных параметрах – идентификатор пользователя. Процесс длился около 2 минут. По окончанию расчета данные были экспортированы в Excel и там сравнивались. С отсутствием текстов процедур – согласен, однако их (участвующих в данном расчете) довольно много (около 10 страниц). Вот вкратце то, что они делают: минимальной расчетной единицей является земельный участок. Договор аренды может содержать несколько участков, а у каждого арендатора может быть несколько договоров или земельных участков (если договор не оформлен). Информация о каждом земельном участке это несколько строк в таблице – по одной на каждое изменение с указанием даты (напр. площадь, коэффициенты, расписания платежей (отдельная таблица) и др.). Цена земли тоже меняется в зависимости от даты и хранится в собственной таблице. Эти данные + стартовые (или переходные) сальдо используются для построения начислений. Далее происходит самое интересное – разброс платежей. Как я уже говорил – минимальная расчетная единица – земельный участок. Однако арендаторы в основном платят за все свои участки и договора одной платежкой, редко указывая за что конкретно они платят, а картинку надо видеть по каждому договору или участку отдельно. Вот и занимается хитрый алгоритм делением этих платежек из условия получения min задолженности или одинаковой переплаты по каждой расчетной единице. После деления платежей производится начисление пени (или фиксированный % в сутки, или учетной ставке банка, которая тоже меняется), а затем – распределение платежек по пене. Когда получена полная картинка по арендатору – определяется, сколько он должен на заданную дату и, если должен, выводится в отчет. По поводу UDF – во всех этих хитромудрых расчетах они действительно используются. Не так как описано в статье Попова (основной алгоритм реализован на DML), однако их некорректное выполнение может привести к ошибочным результатам. Например, ряд UDF функций используется при формировании расписания платежей. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2003, 16:11 |
|
Cтранное поведение IB
|
|||
---|---|---|---|
#18+
Привет! Похоже, что у тебя действительно есть какая-то непростая проблема. Помочь тебе дистанционно не выходит - у меня, во всяком случае. Я подозреваю, что здесь либо какая-то неучтенная промашка/ошибка в твоем проектировании (может, UDF, может, еще что?) - это 70% вероятности, либо баг сервера - 30%, либо что-то еще - ??% Совет дам единственно возможный - необходимо локализовать эту ошибку в виде тестового примера и передать его на тестирование разработчикам - ребята из Firebird или Yaffil всегда готовы исправить баг, да и мне будет интересно с ним разобраться. Разумеется, это не слишком благодарная работа - но если есть возможность локализовать проблему и отследить, как она возникает и из-за чего, то было бы замечательно сделать такой тест. Обычно такие тесты делаются путем постепенного выкидывания частей и изучения поведения - пока не останется минимальный код+схема БД, необходимые для воспроизведения бага. Только так мы сможем разобраться - в чем же дело. С уважением, Алексей. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2003, 12:26 |
|
Cтранное поведение IB
|
|||
---|---|---|---|
#18+
Привет Алексей. Я попробую за выходные избавиться от использования UDF в расчетах - после прочтения статьи Попова основные подозрения у меня возникают именно на них. Если найду у себя Firebird, попробую завести все это под ним. Ну ели в результате моих "стараний" ничего не получится - тогда буду просить помощи. С уважением, Андрей. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2003, 17:25 |
|
|
start [/forum/topic.php?fid=40&fpage=529&tid=1580937]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
33ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
40ms |
get tp. blocked users: |
2ms |
others: | 11ms |
total: | 128ms |
0 / 0 |