Страница 1 из 1

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

Добавлено: 28 авг 2008, 10:30
Zoran
Добрый день всем!

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

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

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

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

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

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

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

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

Добавлено: 28 авг 2008, 15:17
kdv
Если смотерть через 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.
То есть, в транзакции с такими параметрами не будут видны никакие изменения базы данных (кроме тех, которые выполнены в этой транзакции). Это является самой известной проблемой для начинающих разработчиков, когда "приложение видит изменения только после перезапуска.
"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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'ом посмотрю. Возможно действительно станет понятнее. Спасибо за совет!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Добавлено: 01 сен 2008, 17:49
Zoran
не увидел в коде ни единой строки, которая бы связывала транзакцию с компонентом 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" тогда все срастется. (Мне этот вариант больше нравится) так?

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

Добавлено: 01 сен 2008, 18:14
Merlin
Имхо зря стараетесь, ребята. Медицина здесь бессильна - аффтар беседует с зеркалом, а не с вами.

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

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

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

Добавлено: 02 сен 2008, 08:46
Tonal
В общем то понятно где ошибка - в кривой эмуляции вложенных транзакций.
Сценарий облома такой:

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

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

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

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

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

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