Найдено 24 результата
- Вт 05 ноя 2013 14:35
- Форум: SQL Server Data Access Components
- Тема: Можно ли избежать неявной транзакции?
- Ответы: 19
- Просмотры: 19135
- Чт 31 окт 2013 17:20
- Форум: SQL Server Data Access Components
- Тема: Можно ли избежать неявной транзакции?
- Ответы: 19
- Просмотры: 19135
Re: Можно ли избежать неявной транзакции?
Всё же придётся ещё раз вернуться к этому вопросу. Что рекомендуется делать, если нужна распределённая транзакция?
- Вт 29 окт 2013 11:41
- Форум: SQL Server Data Access Components
- Тема: Можно ли избежать неявной транзакции?
- Ответы: 19
- Просмотры: 19135
Re: Можно ли избежать неявной транзакции?
Спасибо за терпение! Перевёл всё на ApplyUpdates наборов данных и сделал свою управляемую транзакцию, всё работает, как хотел.
- Пн 28 окт 2013 16:44
- Форум: SQL Server Data Access Components
- Тема: Можно ли избежать неявной транзакции?
- Ответы: 19
- Просмотры: 19135
Re: Можно ли избежать неявной транзакции?
Спасибо за ссылку, в курсе. Проблема не в том, чтобы правильно сохранить данные, а в том, чтобы сохранить их любой ценой. Вы заранее предполагаете бизнес-процесс, который должен быть правильным со всех сторон, и это работает в 95% случаев. Но бывают случаи, когда информация должна быть просто сохранена, с её корректностью будут разбираться потом отдельными методами. И это очень неудобно - несимметричное управление транзакцией. Я, если честно, никак не пойму смысла в отключении половины функциональности. То есть, программа местами не доступна для управления программисту, это усложняет работу, приходится искать обходные пути. Можно, конечно, в первой же строке хранимой процедуры написать rollback и дальше уже спокойно разбираться самому, но, согласитесь, это как-то странно выглядит, да и не всегда возможно. Очень, очень печально, что нельзя целиком управлять транзакцией.
- Пт 25 окт 2013 10:24
- Форум: SQL Server Data Access Components
- Тема: Можно ли избежать неявной транзакции?
- Ответы: 19
- Просмотры: 19135
Re: Можно ли избежать неявной транзакции?
Понятно, спасибо. Попробую использовать TMSQuery.ApplyUpdates. Просто мне показалось нелогичным такое несимметричное управление транзакцией: транзакция открывается обязательно, а вот завершается или нет - ещё посмотрим. Если обновление данных выполняется достаточно сложной процедурой, внутри которой в зависимости от условий могут быть организованы разные транзакции или не организованы вовсе, то на уровне этой процедуры невозможно определить, кто начал транзакцию, клиент или сервер, соответственно, кто должен принять решение об её откате или фиксации. Это накладывает ненужные ограничения на алгоритмы и приводит к необоснованному усложнению разработки. На мой взгляд, логичнее было бы отключать не завершение транзакции, а всю транзакцию, то есть, если свойство, аналогичное AutoCommit, установлено, то и BEGIN TRANSACTION, и COMMIT/ROLLBACK генерируются компонентой. Если это свойство сброшено, то программист сам вызывает StartTransaction, Commit и Rollback в случае необходимости, или не использует транзакцию вовсе, обеспечивая целостность данных на уровне БД. При такой реализации ограничений нет.
Например, у меня многие хранимые процедуры (практически любая) могут быть вызваны как из клиента, так и из других процедур или скрипта. При этом транзакции контролируются следующим образом:
При таком подходе процедура не в состоянии определить, начал ли транзакцию клиент, или вызывающая процедура, или скрипт, и своей транзакции не откроет. Тогда закрывать транзакцию обязательно придётся на стороне клиента, и механизм управления завершением транзакции с помощью AutoCommit становится бесполезен. Если отключение транзакции на стороне клиента будет полным, то такого не произойдёт, и серверные процедуры отработают правильно. Можно сказать - не используйте такой подход в хранимых процедурах - но бывают ситуации, когда только на уровне процедуры можно принять решение, открывать ли транзакцию и сколько.
Например, у меня многие хранимые процедуры (практически любая) могут быть вызваны как из клиента, так и из других процедур или скрипта. При этом транзакции контролируются следующим образом:
Код: Выделить всё
declare @iRes int, @bTrans bit;
if @@trancount = 0
begin
set @bTrans = 1;
begin transaction;
end
else
set @bTrans = 0;
set @iRes = 0;
--основной код с перехватом ошибок и установкой кода возврата в @iRes
if @bTrans = 1
begin
if @iRes < 0
rollback
else
commit;
end;
return(@iRes);
- Чт 24 окт 2013 15:51
- Форум: SQL Server Data Access Components
- Тема: Можно ли избежать неявной транзакции?
- Ответы: 19
- Просмотры: 19135
Re: Можно ли избежать неявной транзакции?
Другими словами, она обязательно будет открыта, или мной через вызов StartTransaction, или автоматически из ApplyUpdates? То есть, отключить транзакцию вообще невозможно?
- Чт 24 окт 2013 14:54
- Форум: SQL Server Data Access Components
- Тема: Можно ли избежать неявной транзакции?
- Ответы: 19
- Просмотры: 19135
Re: Можно ли избежать неявной транзакции?
Спасибо. А в этом случае использование StartTransaction не предполагается? Открываться транзакция будет по-прежнему автоматически?
- Ср 23 окт 2013 18:03
- Форум: SQL Server Data Access Components
- Тема: Можно ли избежать неявной транзакции?
- Ответы: 19
- Просмотры: 19135
Можно ли избежать неявной транзакции?
При выполнении ApplyUpdates компонента MSConnection самостоятельно сначала открывает транзакцию, затем по результатам либо фиксирует, либо откатывает. У меня довольно сложный процесс сохранения, который разбит на несколько частей, и все части должны быть заключены в транзакционные скобки. Но сделать это я не могу, так как уже первый ApplyUpdates завершает транзакцию. Можно ли как-то запретить MSConnection управлять транзакцией?
- Чт 07 фев 2013 15:30
- Форум: SQL Server Data Access Components
- Тема: Как реализовать "цепочку" изменений?
- Ответы: 10
- Просмотры: 10570
Re: Как реализовать "цепочку" изменений?
Хотя и немного поздновато уже, но добавлю ещё один вариант: для получения данных использовать не запрос к объединённым таблицам, а запрос к представлению, в котором эти таблицы уже объединены, а для изменения данных в таблицах использовать триггеры типа INSTEAD OF этого представления. По-моему, это простое и гибкое решение.
- Ср 31 окт 2012 09:34
- Форум: SQL Server Data Access Components
- Тема: Принудительное обновление записи
- Ответы: 17
- Просмотры: 19795
Re: Принудительное обновление записи
Всё понятно, большое спасибо за разъяснения!
- Вт 30 окт 2012 16:08
- Форум: SQL Server Data Access Components
- Тема: Принудительное обновление записи
- Ответы: 17
- Просмотры: 19795
Re: Принудительное обновление записи
А если число изменений меньше, чем UpdateBatchSize? То есть, UpdateBatchSize = 10, а изменили 7 записей и нажали кнопку "Сохранить". Работа уже в принципе завершена, больше ничего делать не нужно, а RefreshRecord по-прежнему будет отказываться работать? Как её заставить обновить запись в таком случае?
- Пн 29 окт 2012 15:33
- Форум: SQL Server Data Access Components
- Тема: Принудительное обновление записи
- Ответы: 17
- Просмотры: 19795
Re: Принудительное обновление записи
В примере выполняется вот такой код:
Из него видно, что RefreshRecord всегда, при любых условиях вызывается строго после отправки запроса на вставку записи на сервер. То есть, к моменту выполнения RefreshRecord запись на сервере уже есть. Да и значения это не имеет, поскольку RefreshRecord не делает никаких прямых проверок наличия записи на сервере, во всяком случае, в Wireshark я ничего такого не увидел. Или не разглядел?
Согласен, решение проблемы найдено, просто хочется разобраться с механизмом работы компонента, чтобы уверенней с ним работать.
Код: Выделить всё
procedure TForm4.MSQuery1UpdateRecord(DataSet: TDataSet;
UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
begin
case UpdateKind of
DB.ukInsert: InsertRecord(DataSet);
DB.ukModify: ModifyRecord(DataSet);
DB.ukDelete: DeleteRecord(DataSet);
end;
UpdateAction := uaApplied;
end;
procedure TForm4.InsertRecord(DataSet: TDataSet);
var
i: integer;
begin
SQLExecutor.SQL.Clear();
SQLExecutor.SQL.Add('insert into vwApplication (sName, sDescription) values (:sName, :sDescription);');
SQLExecutor.SQL.Add('set :idApplication = scope_identity();');
SQLExecutor.ParamByName('idApplication').ParamType := ptInputOutput;
for i := 0 to SQLExecutor.ParamCount - 1 do
SQLExecutor.Params[i].Value := DataSet[SQLExecutor.Params[i].Name];
SQLExecutor.Execute();
MSQuery1.SQLRefresh.Text := Format('select idApplication from vwApplication where idApplication = %s',
[SQLExecutor.ParamByName('idApplication').AsString]);
MSQuery1.RefreshRecord();
end;
Согласен, решение проблемы найдено, просто хочется разобраться с механизмом работы компонента, чтобы уверенней с ним работать.
- Чт 25 окт 2012 13:28
- Форум: SQL Server Data Access Components
- Тема: Принудительное обновление записи
- Ответы: 17
- Просмотры: 19795
Re: Принудительное обновление записи
Отправил.
- Чт 25 окт 2012 09:35
- Форум: SQL Server Data Access Components
- Тема: Принудительное обновление записи
- Ответы: 17
- Просмотры: 19795
Re: Принудительное обновление записи
В завершение, RefreshRecord() не выполняла обращение к серверу при CachedUpdates = true и Options.UpdateBatchSize > 1. При Options.UpdateBatchSize = 1 запрос из SQLRefresh на сервер отправляется нормально.
- Ср 24 окт 2012 14:17
- Форум: SQL Server Data Access Components
- Тема: Принудительное обновление записи
- Ответы: 17
- Просмотры: 19795
Re: Принудительное обновление записи
Вопрос снимается: начал готовить пример и нашёл у себя ошибку. Спасибо за терпение!