Транзакции в MyQuery
Транзакции в MyQuery
Подскажите, как правилно пользоваться транзакциями.
У меня есть несколко запросов, типа UPDATE и SELECT но разными query на разных формах, мне надо в случае ошибки данные не записывать.
Где можно посмотреть примеры с MyQuery работающие с SET AUTOCOMMIT, BEGIN,COMMIT,ROLLBACK? Можно их использовать, когда разные Query?Будут они связанные между собой в разных Query или будут независимые?
У меня есть несколко запросов, типа UPDATE и SELECT но разными query на разных формах, мне надо в случае ошибки данные не записывать.
Где можно посмотреть примеры с MyQuery работающие с SET AUTOCOMMIT, BEGIN,COMMIT,ROLLBACK? Можно их использовать, когда разные Query?Будут они связанные между собой в разных Query или будут независимые?
Примеры:Вместо использования данных MySQL запросов мы советуем использовать методы StartTransaction, Commit и Rollback компонента TMyConnection. Пример:Транзакция открывается для сессии, поэтому все изменения в разных датасетах использующих одну сессию будут приниматься или откатываться одновременно.
Код: Выделить всё
MyQuery.Connection := MyConnection;
MyQuery.SQL.Text := 'select * from tablename';
MyQuery.Open;
MyConnection.ExecSQL('set autocommit = 0', []);
try
MyQuery.Edit;
MyQuery.FieldByName('fieldname').AsString := 'test';
MyQuery.Post;
MyConnection.ExecSQL('commit', []);
except
MyConnection.ExecSQL('rollback', []);
end;
Код: Выделить всё
MyQuery.Connection := MyConnection;
MyQuery.SQL.Text := 'select * from tablename';
MyQuery.Open;
MyConnection.ExecSQL('start transaction', []);
try
MyQuery.Edit;
MyQuery.FieldByName('fieldname').AsString := 'test';
MyQuery.Post;
MyConnection.ExecSQL('commit', []);
except
MyConnection.ExecSQL('rollback', []);
end;
Код: Выделить всё
MyQuery.Connection := MyConnection;
MyQuery.SQL.Text := 'select * from tablename';
MyQuery.Open;
MyConnection.StartTransaction;
try
MyQuery.Edit;
MyQuery.FieldByName('fieldname').AsString := 'test';
MyQuery.Post;
MyConnection.Commit;
except
MyConnection.Rollback;
end;
Re: Транзакции в MyQuery
Почему у меня не работает так транзакция?
Сдесь более продробно расписано http://www.sql.ru/forum/actualthread.aspx?tid=941472
Также могу добавить, что последний из выше приведеных примеров работает. А этот нет.
Сдесь более продробно расписано http://www.sql.ru/forum/actualthread.aspx?tid=941472
Также могу добавить, что последний из выше приведеных примеров работает. А этот нет.
Код: Выделить всё
try
DM.MyConnection1.StartTransaction;
with DM.MyQuery1 do
begin
Close;
sql.text:='INSERT INTO Org( ID_Tip_O, NK, ND, Kom)'
+' VALUES ( :ID_Tip_O, :NK, :ND, :Kom)';
Params[0].Value:=s[12];
Params[1].Value:=s[2];
Params[2].Value:=s[3];
Params[3].Value:=s[4];
ExecSQL;
end;
if ListView1.Items.Count>0 then
begin
for i:=0 to ListView1.Items.Count-1 do
begin
with DM.MyQuery1 do
begin
Close;
sql.text:='INSERT INTO Org_Kont( ID_Org, ID_Tip, N)'
+' VALUES ( :ID_Org, :ID_Tip, :N)';
Params[0].Value:=s[15];
Params[1].Value:=s[16];
Params[2].Value:=ListView1.Items[i].SubItems[2];
ExecSQL;
end;
end;
end;
end;
DM.MyConnection1.Commit;
except
DM.MyConnection1.Rollback;
end;
Re: Транзакции в MyQuery
Данная проблема вызвана установкой свойства TMyQuery.FetchAll в False. Если FetchAll=True , TMyQuery получает с сервера все данные сразу, если FetchAll=False , данные получаются по мере необходимости, что позволяет экономить ресурсы клиента. Но при FetchAll=False выполнение запросов блокирует текущую сессию. Для избежания этого MyDAC создает дополнительную сессию, которая выполняется вне контекста транзакции. Это приводит к тому что методы TMyConnection.Commit и TMyConnection.Rollback главной сессии не учитывают изменений сделанных в дополнительных сессиях. Для решения проблемы Вы можете использовать один из следующих подходов:
1. Установить TMyQuery.FetchAll в True.
2. Оставить TMyQuery.FetchAll=False и установить TMyQuery.Options.CreateConnection в False. TMyQuery.Options.CreateConnection определяет создавать или нет дополнительные сессии.
3. Использовать компонент TMyCommand вместо TMyQuery для выполнения запросов не возвращающих данных (INSERT, UPDATE, DELETE).
1. Установить TMyQuery.FetchAll в True.
2. Оставить TMyQuery.FetchAll=False и установить TMyQuery.Options.CreateConnection в False. TMyQuery.Options.CreateConnection определяет создавать или нет дополнительные сессии.
3. Использовать компонент TMyCommand вместо TMyQuery для выполнения запросов не возвращающих данных (INSERT, UPDATE, DELETE).
Re: Транзакции в MyQuery
Спасибо.
Re: Транзакции в MyQuery
Я рад что смог помочь. Если у Вас возникнут дальнейшие вопросы по MyDAC, пишите нам.
Re: Транзакции в MyQuery
Понекропостю.
INSERTtttt - ошибка сделана специально что бы вызвать исключение. После исключения должен отработать Rollback и откатить первый INSERT, но этого не происходит. Вместо этого в этой таблице создаются аж 2 индентичные записи. FetchAll = True. CreateConnection = False.
Пробовал с MyConnection.ExecSQL('set autocommit = 0', []); результат тот же. Посоветуйте в какую сторону копать.
Код: Выделить всё
con1.StartTransaction;
try
myqry1.SQL.Clear;
myqry1.SQL.Add('INSERT INTO shop_brands (url) VALUES ('+QuotedStr(Translit_URL(S))+');');
myqry1.SQL.Add('SELECT @@IDENTITY;');
myqry1.ExecSQL;
id:=myqry1.Fields[0].AsInteger;
myqry1.SQL.Add('INSERTtttt INTO shop_brands_i18n (id,locale,name,meta_title,meta_description,meta_keywords) VALUES ('+
IntToStr(id)+', ''ru'', ' +
QuotedStr(S)+', '+QuotedStr(S)+', '+QuotedStr(S)+', '+QuotedStr(S)+');');
myqry1.ExecSQL;
con1.Commit;
except
con1.Rollback;
end;
Пробовал с MyConnection.ExecSQL('set autocommit = 0', []); результат тот же. Посоветуйте в какую сторону копать.
Re: Транзакции в MyQuery
К сожалению, мы не смогли воспроизвести проблему описанным Вами способом. Пожалуйста, обновите MyDAC до последней версии (8.4.12) и, если это не решит проблему, пришлите небольшой пример на viktorv*devart*com, демонстрирующий проблему, включающий скрипт на создание и заполнение таблиц БД.
2 идентичные записи в таблице "shop_brands" создаются потому, что Вы используете метод myqry1.SQL.Add и после второго вызова myqry1.ExecSQL опять выполняется запрос "INSERT INTO shop_brands", для решение этой проблемы Вы можете использовать вместо метода myqry1.SQL.Add свойство myqry1.SQL.Text или перед вызовом myqry1.SQL.Add вызвать метод myqry1.SQL.Clear.
2 идентичные записи в таблице "shop_brands" создаются потому, что Вы используете метод myqry1.SQL.Add и после второго вызова myqry1.ExecSQL опять выполняется запрос "INSERT INTO shop_brands", для решение этой проблемы Вы можете использовать вместо метода myqry1.SQL.Add свойство myqry1.SQL.Text или перед вызовом myqry1.SQL.Add вызвать метод myqry1.SQL.Clear.
Re: Транзакции в MyQuery
Здравствуйте!
Работаю в Delphi 7, установлен MyDAC 7.1.6.
Есть tDBGridEh, связанный с tDataSource-tMyQuery-tMyConnection
Таблица в БД MySQL типа InnoDB. Свойство MyQuery.FetchAll=true.
При создании формы ставлю MyConnection1.StartTransaction
В DBGridEh редактирую данные, потом жму на соответствующую кнопку для MyConnection1.Commit либо MyConnection1.Rollback.
Выяснилось, что в любом случае происходит запись данных в таблицу, Rollback не срабатывает, ошибок при этом не возникает. Насчет работы Commit ничего не могу сказать, т.к. запись происходит как при его наличии, так и при его отсутствии.
Попытка писать через MyConnection.ExecSQL('set autocommit = 0', []); и MyConnection.ExecSQL('rollback', []); также не работает - нет отмены транзакции.
Перечитал практически весь форум, перепробовал предлагаемые варианты, решения моего вопроса не нашел. Подскажите, как идет работа с транзакциями, может чего пропустил.
Работаю в Delphi 7, установлен MyDAC 7.1.6.
Есть tDBGridEh, связанный с tDataSource-tMyQuery-tMyConnection
Таблица в БД MySQL типа InnoDB. Свойство MyQuery.FetchAll=true.
При создании формы ставлю MyConnection1.StartTransaction
В DBGridEh редактирую данные, потом жму на соответствующую кнопку для MyConnection1.Commit либо MyConnection1.Rollback.
Выяснилось, что в любом случае происходит запись данных в таблицу, Rollback не срабатывает, ошибок при этом не возникает. Насчет работы Commit ничего не могу сказать, т.к. запись происходит как при его наличии, так и при его отсутствии.
Попытка писать через MyConnection.ExecSQL('set autocommit = 0', []); и MyConnection.ExecSQL('rollback', []); также не работает - нет отмены транзакции.
Перечитал практически весь форум, перепробовал предлагаемые варианты, решения моего вопроса не нашел. Подскажите, как идет работа с транзакциями, может чего пропустил.
Re: Транзакции в MyQuery
вопрос перенес в новую тему
Re: Транзакции в MyQuery
Мы ответили вам на форуме viewtopic.php?t=14285