我已经对此进行了广泛的搜索,我发现很多人都在问这个问题,但没有答案包含代码示例来帮助我理解。
我想编写一个执行多个更新语句的事务(在sql中使用命令行sqlite3接口),如果它们中的任何一个因任何原因而失败,则回滚事务。默认行为似乎是回滚失败的语句,但提交其他语句。
This tutorial似乎建议在声明之前和之后添加begin;
和rollback;
就足够了,但事实并非如此,因为我已经尝试了故意错误而非错误陈述肯定是犯了(我不想要)。
This example确实让我感到困惑,因为两位对话者似乎最终给出了相互矛盾的建议 - 一个人说你需要编写错误处理(没有给出任何例子),而另一个则说不需要进行错误处理。
我的MWE如下:
create table if not exists accounts (
id integer primary key not null,
balance decimal not null default 0
);
insert into accounts (id, balance) values (1,200),(2,300);
begin transaction;
update accounts set balance = field1 - 100 where id = 1;
update accounts set balance = field1 + 100 where id = 2;
update accounts set foo = 23; //Deliberate error
commit;
我们的想法是不应该提交任何这些更改。
答案 0 :(得分:0)
答案 1 :(得分:-1)
如果你逐行执行,那么你首先运行这些命令的想法是:
create table if not exists accounts (
id integer primary key not null,
balance decimal not null default 0
);
insert into accounts (id, balance) values (1,200),(2,300);
begin transaction;
update accounts set balance = field1 - 100 where id = 1;
update accounts set balance = field1 + 100 where id = 2;
update accounts set foo = 23; //Deliberate error
此时,如果没有错误,则运行commit:
commit;
如果您打开第二个连接并查询该表,则所有更新都应该可见。
另一方面,如果您收到错误,而不是提交回滚:
rollback;
应回滚所有更新;
如果你在java中以编程方式进行,你可以将更新包含在try-catch块中,并在try结束时提交,或者在catch中回滚。