Пропадают введенные записи
Модератор: kdv
Пропадают введенные записи
Добрый день всем!
У меня возникает следующая ситуация:
При многопользовательской работе с Firebird 1.5 изредка пропадают введенные записи.
Т.е.: Несколько пользователей одновременно работают с системой и вводят записи. Получается так, что один из них свои введенные записи видит, а другие введенные им записи не видят. После перезапуска приложения пользователем свои данные не видит и сам. Ситуация возникает достаточно редко и с разными таблицами. По-этому под отладчиком ее найти или смоделировать невозможно.
Может кто сталкивался, в чем может быть проблема? Я думаю это из-за транзакций. Т.е. Какая-то транзакция не принимается и не откатывается и все остальные запросы работают для этого пользователя в рамках потерянной транзакции. Но это только догадки....
Система написана на Delphi. Причем в трех-звенной архитектуре. Серверная часть взаимодействует с сервером БД под одной учетной записью. здесь проблем быть не долно. В настройках cервера уровень изоляции транзакций установлен в DEFAULT. При выполнении запросов все они вроде как включены в блок try-except с явным вызовом StartTransaction - Commit/RollBack. 100%, что все - не дам, но вроде как...
Соответственно вопросы:
1. Какие возможные направления решения проблемы.
2. Как их можно смоделировать искусственно под отладчиком.
У меня возникает следующая ситуация:
При многопользовательской работе с Firebird 1.5 изредка пропадают введенные записи.
Т.е.: Несколько пользователей одновременно работают с системой и вводят записи. Получается так, что один из них свои введенные записи видит, а другие введенные им записи не видят. После перезапуска приложения пользователем свои данные не видит и сам. Ситуация возникает достаточно редко и с разными таблицами. По-этому под отладчиком ее найти или смоделировать невозможно.
Может кто сталкивался, в чем может быть проблема? Я думаю это из-за транзакций. Т.е. Какая-то транзакция не принимается и не откатывается и все остальные запросы работают для этого пользователя в рамках потерянной транзакции. Но это только догадки....
Система написана на Delphi. Причем в трех-звенной архитектуре. Серверная часть взаимодействует с сервером БД под одной учетной записью. здесь проблем быть не долно. В настройках cервера уровень изоляции транзакций установлен в DEFAULT. При выполнении запросов все они вроде как включены в блок try-except с явным вызовом StartTransaction - Commit/RollBack. 100%, что все - не дам, но вроде как...
Соответственно вопросы:
1. Какие возможные направления решения проблемы.
2. Как их можно смоделировать искусственно под отладчиком.
Re: Пропадают введенные записи
у транзакций уровень изолированности snapshotПосле перезапуска приложения пользователем свои данные не видит и сам.
www.ibase.ru/devinfo/ibtrans.htm
у сервера нет такой настройки.В настройках cервера уровень изоляции транзакций установлен в DEFAULT
учить транзакции.Какие возможные направления решения проблемы.
Re: Пропадают введенные записи
Если смотерть через IBExpert (свойства подключения) - то естьу сервера нет такой настройки.В настройках cервера уровень изоляции транзакций установлен в DEFAULT
Это не вариант. Я программер, а не админ. С точки зрения программирования - все отлично. Каждое обращение к обрамлено блоком try-except с явным вызовом StartTransaction - Commit/RollBack.учить транзакции.Какие возможные направления решения проблемы.
А че там делается на сервере... Я не могу стать ГУРУ в каждой СУБД, под которую пишу. По-этому и прошу на форуме помощи. В факе искал - схожей проблемы не нашел! А самостоятельно разбираться и экспериментировать - нереально.
Re: Пропадают введенные записи
у сервера? это у IBExpert default. не пудрите мозги себе и другим. транзакцию стартует приложение, или ваше, или IBExpert, и транзакция работает с тем уровнем изолированности, который задан именно приложением. Если не задан - будет snapshot. То есть то, что Вы и наблюдаете - чужие изменения не видны приложением. Так и должно быть, с транзакциями. Нужные параметры транзакций задаете Вы сами, в приложении.Если смотерть через IBExpert (свойства подключения) - то есть
Вы знаете, начинаю сомневаться, что "программер". Я Вам про параметры транзакций, а Вы мне про их старт. Вы прочитали статью, на которую я дал ссылку?Я программер, а не админ. С точки зрения программирования - все отлично. Каждое обращение к обрамлено блоком try-except с явным вызовом StartTransaction - Commit/RollBack.
Приложения какие компоненты используют? Если IBX, то обязательно читать вот это
http://www.ibase.ru/devinfo/ibx.htm#ibtransaction
"В параметрах транзакции (картинка слева, вызывается по двойному клику на компоненте, или при нажатии кнопки ... в свойстве Params) указываются константы, соответствующие IB API (без префикса isc_tpb_). Если параметры не указаны (пусто), то IBX использует параметры транзакции по умолчанию, которые соответствуют уровню изолированности snapshot+wait+write.
То есть, в транзакции с такими параметрами не будут видны никакие изменения базы данных (кроме тех, которые выполнены в этой транзакции). Это является самой известной проблемой для начинающих разработчиков, когда "приложение видит изменения только после перезапуска."
Re: Пропадают введенные записи
это вообще какой-то отмаз, я даже не знаю как назвать.А самостоятельно разбираться и экспериментировать - нереально.
если Вы работаете с СУБД, то в первую очередь надо разбираться, что там с транзакциями.
если разбираться "нереально" - то тогда нет смысла программировать.
Re: Пропадают введенные записи
канделябром его, канделябром. =)kdv писал(а):это вообще какой-то отмаз, я даже не знаю как назвать.А самостоятельно разбираться и экспериментировать - нереально.
если Вы работаете с СУБД, то в первую очередь надо разбираться, что там с транзакциями.
если разбираться "нереально" - то тогда нет смысла программировать.
а то тут научат сервер транзакциями управлять =)
Re: Пропадают введенные записи
Спасибо поржал.Zoran писал(а):Это не вариант. Я программер, а не админ. С точки зрения программирования - все отлично. Каждое обращение к обрамлено блоком try-except с явным вызовом StartTransaction - Commit/RollBack.учить транзакции.
Параметры транзакции определяют поведение программы, вообще-то.
Или у тебя "точка зрения программирования" - это синтаксическая корректность программ? Тогда компилятор сам это проверяет и непонятно зачем при этом программист. Неужели чтобы порождать случайные, синтаксически корректные последовательности символов?
Re: Пропадают введенные записи
To: Tonal, Attid - Попытка за насмешками скрыть собственную безграммотность не делает вам чести. Если вам нечего ответить ПО ТЕМЕ - то можно просто промолчать.
To: kdv - Спасибо за ответ. Я надеялся, что есть чудесный способ настройки на стороне сервера параметров старта транзакций (по умолчанию) .
Я ознакомился со статьей, но для меня остался непонятным следующий момент:
Настройки в приложении у меня установлены в точности как на картинке http://www.ibase.ru/devinfo/ibx.htm#ibtransaction .
Я бы понял, если бы исчезала одна команда. Но мне непонятно почему исчезает несколько, причем пользователь видит их в рамках своей сессии как выполненные.
Т.е. в результате работы пользователь выполняет команды (например):
добавить запись
добавить запись
добавить запись
открыть набор
добавить запись
добавить запись (отметка)
добавить запись
добавить запись
завершить работу.
Но начиная от (отметка) сохраненных данных нет. Я так понимаю в рамках одной транзакции выполняется одна команда "добавить запись". После это выполняется киммит или роллбак. Когда выполняется следующая команда "добавить запись" - она выполняется в рамках другой транзакции. Или это не так?
Не могли бы вы разжевать для меня этот момент. Премного благодарен!
To: kdv - Спасибо за ответ. Я надеялся, что есть чудесный способ настройки на стороне сервера параметров старта транзакций (по умолчанию) .
Я ознакомился со статьей, но для меня остался непонятным следующий момент:
Настройки в приложении у меня установлены в точности как на картинке http://www.ibase.ru/devinfo/ibx.htm#ibtransaction .
Я бы понял, если бы исчезала одна команда. Но мне непонятно почему исчезает несколько, причем пользователь видит их в рамках своей сессии как выполненные.
Т.е. в результате работы пользователь выполняет команды (например):
добавить запись
добавить запись
добавить запись
открыть набор
добавить запись
добавить запись (отметка)
добавить запись
добавить запись
завершить работу.
Но начиная от (отметка) сохраненных данных нет. Я так понимаю в рамках одной транзакции выполняется одна команда "добавить запись". После это выполняется киммит или роллбак. Когда выполняется следующая команда "добавить запись" - она выполняется в рамках другой транзакции. Или это не так?
Не могли бы вы разжевать для меня этот момент. Премного благодарен!
Re: Пропадают введенные записи
не нравятся насмешки - учитесь.Tonal, Attid - Попытка за насмешками скрыть собственную безграммотность не делает вам чести. Если вам нечего ответить ПО ТЕМЕ - то можно просто промолчать.
Вы определитесь, что у Вас в приложении делается.Я так понимаю в рамках одной транзакции выполняется одна команда "добавить запись".
Я например не понимаю, где делаются старты транзакций, где коммиты, и так далее.
ужас какой. еще раз прочитайте ibx.htm, вторую часть, там где про транзакции написано. И возвращайтесь только прочитав, пожалуйста.Когда выполняется следующая команда "добавить запись" - она выполняется в рамках другой транзакции. Или это не так?
Транзакциями управляет клиент и только клиент. Как там у Вас в приложении действия обрамлены транзакциями - я не знаю. Допустим, параметры транзакции прописаны нормально. Значит где-то в приложении или не делается коммит, или делается роллбэк.
Догадаться что происходит, невозможно, потому что Вы даже путаетесь в описании проблемы - то записи не видны другим, то видны одному, то они "исчезают".
Re: Пропадают введенные записи
Пусть автор через какой-нибудь SQL monitor посмотрит, что там и как у него происходит по части коммитов.
Кстати, записи пропадают всегда в одних и тех же случаях или случайным образом?
Кстати, записи пропадают всегда в одних и тех же случаях или случайным образом?
Re: Пропадают введенные записи
А я что делаю? Как раз учусь. Просто кроме того, что искать ответы в литературе и на форумах, я предпочитаю еще и спрашивать. Считаю что так обучение проходит эффективнее. Это позволяет сузить область поиска проблемы и решить ее наиболее эффективно. Есть такая пословица: Правильно поставленный вопрос - это уже половина ответа. В процессе диалога я и для себя пытаюсь сформулировать в чем же может заключаться проблема.не нравятся насмешки - учитесь.
Пример кода:Вы определитесь, что у Вас в приложении делается.
Я например не понимаю, где делаются старты транзакций, где коммиты, и так далее.
Код: Выделить всё
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;
Я не путаюсь, может выражаюсь не однозначно. Для меня "не видны другим" и "видны одному" это равнозначные понятия. Опять же я пытаюсь найти решение проблемы о которой мне рассказывает оператор группы поддержки, а ему рассказывает клиент. Сам я ее смоделировать не смог. Один из моих первых вопросов был как смоделировать ситуацию самому!Вы даже путаетесь в описании проблемы - то записи не видны другим, то видны одному, то они "исчезают".
Схему работы я подробно описал выше. Каждый запрос ДОБАВИТЬ ЗАПИСЬ идет через указанный код. Соответственно обязательно вызываются методы StartTransaction - commit/rollback. Т.о., на мой взгляд, с делано все что можно. Каждый запрос выполняется в рамках отдельной транзакции и почему записи перестают добавляться в определенный момент мне не понятно. Сам пользователь который добавляет записи видит их как добавленные. При перезапуске им программы - записей он уже не видит. Если что-то в схеме не понятно - задайте наводящие вопросы. ТОгда возможно мне станет понятнее, что следует описать подробнее.
Записи пропадают случайным образом.Пусть автор через какой-нибудь SQL monitor посмотрит, что там и как у него происходит по части коммитов.
Кстати, записи пропадают всегда в одних и тех же случаях или случайным образом?
SQL monitor'ом посмотрю. Возможно действительно станет понятнее. Спасибо за совет!
Re: Пропадают введенные записи
Фраза, на которую я отвечал показывает нежелание учится и ничего кроме смеха вызвать не может.Zoran писал(а):To: Tonal, Attid - Попытка за насмешками скрыть собственную безграммотность не делает вам чести. Если вам нечего ответить ПО ТЕМЕ - то можно просто промолчать.
Кроме того, вопрос не содержит достаточной технической информации, на которую можно рассматривать.
Как то: точная версия сервера, супер или классик, операционка сервера и клиентов, язык написания клиента, библиотека доступа и её версия, какие именно запросы на вставку/модификацию выполняются, политика управления транзакциями (сколько транзакций одновременно в клиенте и каких у них параметры) и т.п.
Включив телепатию, на некоторые из этих вопрсов можно ответить, например язык написания клиента видимо Delphi, библиотека IBX, транзакция одна на всё приложение.
Опять же, судя по поведению, которое ты описал, в каком то месте кода коммит просто не делается.
Возможно, что делается Trancaction.Active := False; которая приводит к ролбаку.
Либо где-то вылетает исключение, приводящее к ролбаку, а потом гасится.
Т.е. совершенно ясно, что ошибка в неправильной работе клиентского приложения с транзакциями.
Теперь перечитай свою фразу про то что ты "программист а не админ" и в ответ на совет разобраться с транзакциями, и подумай, что она может вызвать кроме смеха?
Re: Пропадают введенные записи
Наводящие вопросы:
1) Версия делфи и IBX-а.
2) Какими компонентами и как происходит отображение данных?
3) Как происходит создание новой записи (до момента вызова TDirectIBConnection._ExecQuery)?
4) Что будет, если исключение вылетит в _StartTransaction?
1) Версия делфи и IBX-а.
2) Какими компонентами и как происходит отображение данных?
3) Как происходит создание новой записи (до момента вызова TDirectIBConnection._ExecQuery)?
4) Что будет, если исключение вылетит в _StartTransaction?
Re: Пропадают введенные записи
не увидел в коде ни единой строки, которая бы связывала транзакцию с компонентом upd.
то есть, транзакция живет сама по себе, а upd выполняется в фиг-знает какой транзакции - скорее всего в дефолтной, другой, которая неизвестно когда заканчивается. Где написано
upd.Transaction:=...
что такое _StartTransaction вообще ?
где здесь имя компонента IBTransaction???
так что это не код, а муть полная. Код должен был быть примерно таким
я боюсь, что Вы не в курсе, что клиент IB/FB может стартовать сколько угодно транзакций, а не только одну, поэтому жесткая привязка запросов к транзакции обязательна. То есть, фактически Вы не читали ibx.htm
то есть, транзакция живет сама по себе, а upd выполняется в фиг-знает какой транзакции - скорее всего в дефолтной, другой, которая неизвестно когда заканчивается. Где написано
upd.Transaction:=...
что такое _StartTransaction вообще ?
где здесь имя компонента IBTransaction???
так что это не код, а муть полная. Код должен был быть примерно таким
Код: Выделить всё
TR1.StartTransaction;
...
UPd.Transaction:=TR1;
...
TR1.Commit;
...
Re: Пропадают введенные записи
Связывается в ДизайТайме. Delphi 7.0.не увидел в коде ни единой строки, которая бы связывала транзакцию с компонентом upd
Компоненты (Свойства):
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: Пропадают введенные записи
Имхо зря стараетесь, ребята. Медицина здесь бессильна - аффтар беседует с зеркалом, а не с вами.
Re: Пропадают введенные записи
нафиг вообще эти стремные обертки _StartTransaction и _Commit?
извините, но это чушь какая-то.Собственно, а зачем здесь счетчик? Если я его просто выкину, тогда у меня в случае чего пропадет только одна операция
надеюсь, теперь понятно, что этот топик был пустопорожним, и приоблема исключительно в Вашем коде?не представляется возможным, т.к. пользователь может вызвать StartTransaction с помощью встроенного скриптового
Re: Пропадают введенные записи
В общем то понятно где ошибка - в кривой эмуляции вложенных транзакций.
Сценарий облома такой:
То же самое получится, если просто выкинуть счётчик. Тогда Commit вместо Rollback будет работать так же.
Если подобные сценарии существуют, то просто выкидыванием счётчика разрулить их не удастся.
Сценарий облома такой:
Код: Выделить всё
Start
Вводим данные 1
Start
Вводим данные 2
Rollback
Вот здесь, данных 1 в базе уже нет, а клиент думает, что они есть. :)
Commit
Если подобные сценарии существуют, то просто выкидыванием счётчика разрулить их не удастся.
Re: Пропадают введенные записи
Может и так, но пытаясь объяснить как там все устроено другим, я и сам разобрался. Как в старом анегдоте: Я вам объяснял, объяснял, сам понял, а вы все не пониманиете. Самостоятельно в тихой беседе сам с собой я бы еще мог долго тупить....Имхо зря стараетесь, ребята. Медицина здесь бессильна - аффтар беседует с зеркалом, а не с вами.
Соединение с БД сделано через COM объект. Архитектура то трехзвенная. Для того и сделаны эти функции чтоб дергать их с клиента.нафиг вообще эти стремные обертки _StartTransaction и _Commit?
Топик не был пустопорожним. В процессе диалога я осознал, что проблема решается в коде, а не в чудесных настройках на сервере. Опять же нашел нужные куски кода и вероятное место ошибки, раньше у меня и исходников то от этой части не было.надеюсь, теперь понятно, что этот топик был пустопорожним, и приоблема исключительно в Вашем коде?
Всем спасибо! Не считайте, что время потрачено зря!