如何编写回滚任何错误的sqlite事务

时间:2017-05-19 15:45:35

标签: sqlite transactions

我已经对此进行了广泛的搜索,我发现很多人都在问这个问题,但没有答案包含代码示例来帮助我理解。

我想编写一个执行多个更新语句的事务(在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;

我们的想法是不应该提交任何这些更改。

2 个答案:

答案 0 :(得分:0)

sqlite3 command-line shell旨在以交互方式使用,因此您可以在发生错误后继续使用。

要中止第一个错误,请使用while选项:

Board

答案 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中回滚。