Пропадают введенные записи

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
Zoran
Сообщения: 37
Зарегистрирован: 27 авг 2008, 12:08

Пропадают введенные записи

Сообщение Zoran » 28 авг 2008, 10:30

Добрый день всем!

У меня возникает следующая ситуация:
При многопользовательской работе с Firebird 1.5 изредка пропадают введенные записи.
Т.е.: Несколько пользователей одновременно работают с системой и вводят записи. Получается так, что один из них свои введенные записи видит, а другие введенные им записи не видят. После перезапуска приложения пользователем свои данные не видит и сам. Ситуация возникает достаточно редко и с разными таблицами. По-этому под отладчиком ее найти или смоделировать невозможно.
Может кто сталкивался, в чем может быть проблема? Я думаю это из-за транзакций. Т.е. Какая-то транзакция не принимается и не откатывается и все остальные запросы работают для этого пользователя в рамках потерянной транзакции. Но это только догадки....

Система написана на Delphi. Причем в трех-звенной архитектуре. Серверная часть взаимодействует с сервером БД под одной учетной записью. здесь проблем быть не долно. В настройках cервера уровень изоляции транзакций установлен в DEFAULT. При выполнении запросов все они вроде как включены в блок try-except с явным вызовом StartTransaction - Commit/RollBack. 100%, что все - не дам, но вроде как...

Соответственно вопросы:
1. Какие возможные направления решения проблемы.
2. Как их можно смоделировать искусственно под отладчиком.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Пропадают введенные записи

Сообщение kdv » 28 авг 2008, 10:35

После перезапуска приложения пользователем свои данные не видит и сам.
у транзакций уровень изолированности snapshot
www.ibase.ru/devinfo/ibtrans.htm
В настройках cервера уровень изоляции транзакций установлен в DEFAULT
у сервера нет такой настройки.
Какие возможные направления решения проблемы.
учить транзакции.

Zoran
Сообщения: 37
Зарегистрирован: 27 авг 2008, 12:08

Re: Пропадают введенные записи

Сообщение Zoran » 28 авг 2008, 14:17

В настройках cервера уровень изоляции транзакций установлен в DEFAULT
у сервера нет такой настройки.
Если смотерть через IBExpert (свойства подключения) - то есть :)
Какие возможные направления решения проблемы.
учить транзакции.
Это не вариант. Я программер, а не админ. С точки зрения программирования - все отлично. Каждое обращение к обрамлено блоком try-except с явным вызовом StartTransaction - Commit/RollBack.
А че там делается на сервере... Я не могу стать ГУРУ в каждой СУБД, под которую пишу. По-этому и прошу на форуме помощи. В факе искал - схожей проблемы не нашел! А самостоятельно разбираться и экспериментировать - нереально.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Пропадают введенные записи

Сообщение kdv » 28 авг 2008, 15:17

Если смотерть через IBExpert (свойства подключения) - то есть
у сервера? это у IBExpert default. не пудрите мозги себе и другим. транзакцию стартует приложение, или ваше, или IBExpert, и транзакция работает с тем уровнем изолированности, который задан именно приложением. Если не задан - будет snapshot. То есть то, что Вы и наблюдаете - чужие изменения не видны приложением. Так и должно быть, с транзакциями. Нужные параметры транзакций задаете Вы сами, в приложении.
Я программер, а не админ. С точки зрения программирования - все отлично. Каждое обращение к обрамлено блоком try-except с явным вызовом StartTransaction - Commit/RollBack.
Вы знаете, начинаю сомневаться, что "программер". Я Вам про параметры транзакций, а Вы мне про их старт. Вы прочитали статью, на которую я дал ссылку?
Приложения какие компоненты используют? Если IBX, то обязательно читать вот это
http://www.ibase.ru/devinfo/ibx.htm#ibtransaction
"В параметрах транзакции (картинка слева, вызывается по двойному клику на компоненте, или при нажатии кнопки ... в свойстве Params) указываются константы, соответствующие IB API (без префикса isc_tpb_). Если параметры не указаны (пусто), то IBX использует параметры транзакции по умолчанию, которые соответствуют уровню изолированности snapshot+wait+write.
То есть, в транзакции с такими параметрами не будут видны никакие изменения базы данных (кроме тех, которые выполнены в этой транзакции). Это является самой известной проблемой для начинающих разработчиков, когда "приложение видит изменения только после перезапуска.
"

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Пропадают введенные записи

Сообщение kdv » 28 авг 2008, 15:19

А самостоятельно разбираться и экспериментировать - нереально.
это вообще какой-то отмаз, я даже не знаю как назвать.
если Вы работаете с СУБД, то в первую очередь надо разбираться, что там с транзакциями.
если разбираться "нереально" - то тогда нет смысла программировать.

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Re: Пропадают введенные записи

Сообщение Attid » 28 авг 2008, 16:08

kdv писал(а):
А самостоятельно разбираться и экспериментировать - нереально.
это вообще какой-то отмаз, я даже не знаю как назвать.
если Вы работаете с СУБД, то в первую очередь надо разбираться, что там с транзакциями.
если разбираться "нереально" - то тогда нет смысла программировать.
канделябром его, канделябром. =)

а то тут научат сервер транзакциями управлять =)

Tonal
Сообщения: 104
Зарегистрирован: 30 сен 2007, 13:42

Re: Пропадают введенные записи

Сообщение Tonal » 29 авг 2008, 09:25

Zoran писал(а):
учить транзакции.
Это не вариант. Я программер, а не админ. С точки зрения программирования - все отлично. Каждое обращение к обрамлено блоком try-except с явным вызовом StartTransaction - Commit/RollBack.
Спасибо поржал. :lol:

Параметры транзакции определяют поведение программы, вообще-то.
Или у тебя "точка зрения программирования" - это синтаксическая корректность программ? Тогда компилятор сам это проверяет и непонятно зачем при этом программист. Неужели чтобы порождать случайные, синтаксически корректные последовательности символов? :)

Zoran
Сообщения: 37
Зарегистрирован: 27 авг 2008, 12:08

Re: Пропадают введенные записи

Сообщение Zoran » 29 авг 2008, 17:03

To: Tonal, Attid - Попытка за насмешками скрыть собственную безграммотность не делает вам чести. Если вам нечего ответить ПО ТЕМЕ - то можно просто промолчать.

To: kdv - Спасибо за ответ. Я надеялся, что есть чудесный способ настройки на стороне сервера параметров старта транзакций (по умолчанию) :).
Я ознакомился со статьей, но для меня остался непонятным следующий момент:
Настройки в приложении у меня установлены в точности как на картинке http://www.ibase.ru/devinfo/ibx.htm#ibtransaction .
Я бы понял, если бы исчезала одна команда. Но мне непонятно почему исчезает несколько, причем пользователь видит их в рамках своей сессии как выполненные.
Т.е. в результате работы пользователь выполняет команды (например):
добавить запись
добавить запись
добавить запись
открыть набор
добавить запись
добавить запись (отметка)
добавить запись
добавить запись
завершить работу.

Но начиная от (отметка) сохраненных данных нет. Я так понимаю в рамках одной транзакции выполняется одна команда "добавить запись". После это выполняется киммит или роллбак. Когда выполняется следующая команда "добавить запись" - она выполняется в рамках другой транзакции. Или это не так?
Не могли бы вы разжевать для меня этот момент. Премного благодарен!

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Пропадают введенные записи

Сообщение kdv » 29 авг 2008, 17:11

Tonal, Attid - Попытка за насмешками скрыть собственную безграммотность не делает вам чести. Если вам нечего ответить ПО ТЕМЕ - то можно просто промолчать.
не нравятся насмешки - учитесь.
Я так понимаю в рамках одной транзакции выполняется одна команда "добавить запись".
Вы определитесь, что у Вас в приложении делается.
Я например не понимаю, где делаются старты транзакций, где коммиты, и так далее.
Когда выполняется следующая команда "добавить запись" - она выполняется в рамках другой транзакции. Или это не так?
ужас какой. еще раз прочитайте ibx.htm, вторую часть, там где про транзакции написано. И возвращайтесь только прочитав, пожалуйста.
Транзакциями управляет клиент и только клиент. Как там у Вас в приложении действия обрамлены транзакциями - я не знаю. Допустим, параметры транзакции прописаны нормально. Значит где-то в приложении или не делается коммит, или делается роллбэк.
Догадаться что происходит, невозможно, потому что Вы даже путаетесь в описании проблемы - то записи не видны другим, то видны одному, то они "исчезают".

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Re: Пропадают введенные записи

Сообщение CyberMax » 30 авг 2008, 02:45

Пусть автор через какой-нибудь SQL monitor посмотрит, что там и как у него происходит по части коммитов.
Кстати, записи пропадают всегда в одних и тех же случаях или случайным образом?

Zoran
Сообщения: 37
Зарегистрирован: 27 авг 2008, 12:08

Re: Пропадают введенные записи

Сообщение Zoran » 01 сен 2008, 13:09

не нравятся насмешки - учитесь.
А я что делаю? Как раз учусь. Просто кроме того, что искать ответы в литературе и на форумах, я предпочитаю еще и спрашивать. Считаю что так обучение проходит эффективнее. Это позволяет сузить область поиска проблемы и решить ее наиболее эффективно. Есть такая пословица: Правильно поставленный вопрос - это уже половина ответа. В процессе диалога я и для себя пытаюсь сформулировать в чем же может заключаться проблема.
Вы определитесь, что у Вас в приложении делается.
Я например не понимаю, где делаются старты транзакций, где коммиты, и так далее.
Пример кода:

Код: Выделить всё

procedure TDirectIBConnection._ExecQuery(const ASQL: string);
Var
  upd : TIBQuery;
begin
  //начало транзакции
  _StartTransaction;
  try
    //получение запроса и связь его с транзакцией
    upd := _GetQuery(ASQL, FParams.Count > 0);
    if not upd.Prepared then
      upd.Prepare;
    //обнуление  параметров
    _MakeParamsBounded(upd.Params);
    //присвоение переданных параметров запросу
    FParams.AssignToDBParams(upd.Params);
    //исполнение запроса
    upd.ExecSQL;
    //очистка параметров
    _ClearParams(upd.Params);
    //подтверждение транзакции
    _Commit;
  except
    on E:Exception do
    begin
      //отмена всех изменений транзакции
      _Rollback;
      raise;
    end;
  end;
end;
Все запросы на добавление/изменение/удаление идут через этот блок. Соответственно вызывется метод старта транзакции, потом выполняется SQL выражение. Потом вызывается метод Commit, а ва случае ошибки ROLLBACK.

Вы даже путаетесь в описании проблемы - то записи не видны другим, то видны одному, то они "исчезают".
Я не путаюсь, может выражаюсь не однозначно. Для меня "не видны другим" и "видны одному" это равнозначные понятия. Опять же я пытаюсь найти решение проблемы о которой мне рассказывает оператор группы поддержки, а ему рассказывает клиент. Сам я ее смоделировать не смог. Один из моих первых вопросов был как смоделировать ситуацию самому!

Схему работы я подробно описал выше. Каждый запрос ДОБАВИТЬ ЗАПИСЬ идет через указанный код. Соответственно обязательно вызываются методы StartTransaction - commit/rollback. Т.о., на мой взгляд, с делано все что можно. Каждый запрос выполняется в рамках отдельной транзакции и почему записи перестают добавляться в определенный момент мне не понятно. Сам пользователь который добавляет записи видит их как добавленные. При перезапуске им программы - записей он уже не видит. Если что-то в схеме не понятно - задайте наводящие вопросы. ТОгда возможно мне станет понятнее, что следует описать подробнее.

Пусть автор через какой-нибудь SQL monitor посмотрит, что там и как у него происходит по части коммитов.
Кстати, записи пропадают всегда в одних и тех же случаях или случайным образом?
Записи пропадают случайным образом.
SQL monitor'ом посмотрю. Возможно действительно станет понятнее. Спасибо за совет!

Tonal
Сообщения: 104
Зарегистрирован: 30 сен 2007, 13:42

Re: Пропадают введенные записи

Сообщение Tonal » 01 сен 2008, 13:17

Zoran писал(а):To: Tonal, Attid - Попытка за насмешками скрыть собственную безграммотность не делает вам чести. Если вам нечего ответить ПО ТЕМЕ - то можно просто промолчать.
Фраза, на которую я отвечал показывает нежелание учится и ничего кроме смеха вызвать не может.

Кроме того, вопрос не содержит достаточной технической информации, на которую можно рассматривать.
Как то: точная версия сервера, супер или классик, операционка сервера и клиентов, язык написания клиента, библиотека доступа и её версия, какие именно запросы на вставку/модификацию выполняются, политика управления транзакциями (сколько транзакций одновременно в клиенте и каких у них параметры) и т.п.

Включив телепатию, на некоторые из этих вопрсов можно ответить, например язык написания клиента видимо Delphi, библиотека IBX, транзакция одна на всё приложение.

Опять же, судя по поведению, которое ты описал, в каком то месте кода коммит просто не делается.
Возможно, что делается Trancaction.Active := False; которая приводит к ролбаку.
Либо где-то вылетает исключение, приводящее к ролбаку, а потом гасится.

Т.е. совершенно ясно, что ошибка в неправильной работе клиентского приложения с транзакциями.
Теперь перечитай свою фразу про то что ты "программист а не админ" и в ответ на совет разобраться с транзакциями, и подумай, что она может вызвать кроме смеха? :)

Tonal
Сообщения: 104
Зарегистрирован: 30 сен 2007, 13:42

Re: Пропадают введенные записи

Сообщение Tonal » 01 сен 2008, 13:29

Наводящие вопросы:
1) Версия делфи и IBX-а.
2) Какими компонентами и как происходит отображение данных?
3) Как происходит создание новой записи (до момента вызова TDirectIBConnection._ExecQuery)?
4) Что будет, если исключение вылетит в _StartTransaction?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Пропадают введенные записи

Сообщение kdv » 01 сен 2008, 13:43

не увидел в коде ни единой строки, которая бы связывала транзакцию с компонентом upd.
то есть, транзакция живет сама по себе, а upd выполняется в фиг-знает какой транзакции - скорее всего в дефолтной, другой, которая неизвестно когда заканчивается. Где написано
upd.Transaction:=...

что такое _StartTransaction вообще ?
где здесь имя компонента IBTransaction???

так что это не код, а муть полная. Код должен был быть примерно таким

Код: Выделить всё

TR1.StartTransaction;
...
UPd.Transaction:=TR1;
...
TR1.Commit;
...
я боюсь, что Вы не в курсе, что клиент IB/FB может стартовать сколько угодно транзакций, а не только одну, поэтому жесткая привязка запросов к транзакции обязательна. То есть, фактически Вы не читали ibx.htm

Zoran
Сообщения: 37
Зарегистрирован: 27 авг 2008, 12:08

Re: Пропадают введенные записи

Сообщение Zoran » 01 сен 2008, 17:49

не увидел в коде ни единой строки, которая бы связывала транзакцию с компонентом upd
Связывается в ДизайТайме. Delphi 7.0.
Компоненты (Свойства):
TIBDataBase (Name = IBDB)
TIBSQL (name= ibqNewID; dataBase=IBDB; Transaction=ibtrMain)
TIBtransaction (Name = ibtrMain; DefaultDataBase=IBDB)

Процедуры:

Код: Выделить всё

procedure TDirectIBConnection._StartTransaction;
begin
  Inc(FTransCount);
  if FTransCount = 1 then
    ForceStartTransaction;
end;

procedure TDirectIBConnection._Commit;
begin
  if FTransCount > 0 then
    Dec(FTransCount);
  if (FTransCount = 0) then
    ForceCommit;
end;

procedure TDirectIBConnection._Rollback;
begin
  ForceRollback;
end;

procedure TDirectIBConnection.ForceStartTransaction;
begin
  _CheckConnected;
  if not ibtrMain.InTransaction then
    ibtrMain.StartTransaction;
end;

procedure TDirectIBConnection.ForceCommit;
begin
  if ibtrMain.InTransaction then
    ibtrMain.Commit;
  FTransCount := 0;
end;

procedure TDirectIBConnection.ForceRollback;
begin
  if ibtrMain.InTransaction then
    ibtrMain.Rollback;
  FTransCount := 0;
end;
Это в дополнение к предыдущему примеру.

Вроде как дошли до сути. Судя по коду в случае если счетчик FTransCount (по какойто причине) уйдет вперед (количество вызовов StartTransaction будет больше чем и Commit), то коммит транзакции не будет применяться пока счетчик не станет равен 0 или не произойдет ошибка.
Собственно, а зачем здесь счетчик? Если я его просто выкину, тогда у меня в случае чего пропадет только одна операция. Или как вариант можно в _Commit убрать строку "if (FTransCount = 0) then", тогда при вызове коммит транзакция будет всегда завершаться, как и при вызове роллбак.

Я правильно все изложил?
Отследить почему происходит рассогласование количества вызовов не представляется возможным, т.к. пользователь может вызвать StartTransaction с помощью встроенного скриптового языка. :(

Соответственно если я уберу в процедуре _Commit строку "if (FTransCount = 0) then" тогда все срастется. (Мне этот вариант больше нравится) так?

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Re: Пропадают введенные записи

Сообщение Merlin » 01 сен 2008, 18:14

Имхо зря стараетесь, ребята. Медицина здесь бессильна - аффтар беседует с зеркалом, а не с вами.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Пропадают введенные записи

Сообщение kdv » 01 сен 2008, 18:19

нафиг вообще эти стремные обертки _StartTransaction и _Commit?
Собственно, а зачем здесь счетчик? Если я его просто выкину, тогда у меня в случае чего пропадет только одна операция
извините, но это чушь какая-то.
не представляется возможным, т.к. пользователь может вызвать StartTransaction с помощью встроенного скриптового
надеюсь, теперь понятно, что этот топик был пустопорожним, и приоблема исключительно в Вашем коде?

Tonal
Сообщения: 104
Зарегистрирован: 30 сен 2007, 13:42

Re: Пропадают введенные записи

Сообщение Tonal » 02 сен 2008, 08:46

В общем то понятно где ошибка - в кривой эмуляции вложенных транзакций.
Сценарий облома такой:

Код: Выделить всё

Start
Вводим данные 1
Start
Вводим данные 2
Rollback
Вот здесь, данных 1 в базе уже нет, а клиент думает, что они есть. :)
Commit
То же самое получится, если просто выкинуть счётчик. Тогда Commit вместо Rollback будет работать так же.

Если подобные сценарии существуют, то просто выкидыванием счётчика разрулить их не удастся.

Zoran
Сообщения: 37
Зарегистрирован: 27 авг 2008, 12:08

Re: Пропадают введенные записи

Сообщение Zoran » 02 сен 2008, 10:07

Имхо зря стараетесь, ребята. Медицина здесь бессильна - аффтар беседует с зеркалом, а не с вами.
Может и так, но пытаясь объяснить как там все устроено другим, я и сам разобрался. Как в старом анегдоте: Я вам объяснял, объяснял, сам понял, а вы все не пониманиете. Самостоятельно в тихой беседе сам с собой я бы еще мог долго тупить....
нафиг вообще эти стремные обертки _StartTransaction и _Commit?
Соединение с БД сделано через COM объект. Архитектура то трехзвенная. Для того и сделаны эти функции чтоб дергать их с клиента.
надеюсь, теперь понятно, что этот топик был пустопорожним, и приоблема исключительно в Вашем коде?
Топик не был пустопорожним. В процессе диалога я осознал, что проблема решается в коде, а не в чудесных настройках на сервере. Опять же нашел нужные куски кода и вероятное место ошибки, раньше у меня и исходников то от этой части не было.

Всем спасибо! Не считайте, что время потрачено зря!

Ответить