2017-05-19 37 views
1

我已經在這方面進行了廣泛搜索,我發現很多人問這個問題,但沒有答案,包括代碼示例來幫助我理解。如何編寫sqlite事務回滾任何錯誤

我想編寫一個事務(在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

sqlite3 command-line shell旨在交互使用,因此它允許您在發生錯誤後繼續。

要中止上的第一個錯誤,而不是,使用-bail選項:如果你是行執行行

sqlite3 -bail my.db < mwe.sql 
+0

這聽起來很有趣,但我沒有足夠的細節來實現它,特別是因爲谷歌搜索'sqlite -bail選項'沒有提出任何明顯相關的東西? – Max

+0

'-bail'搜索沒有「保釋」一詞的頁面... –

+0

我永遠不會!謝謝! – Max

-1

,然後想法SI您先運行這些命令:

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; 

全部如果打開第二個連接並查詢表,則更新應該可見。

上,如果你得到一個錯誤另一隻手,而不是提交您的回滾:

rollback; 

所有更新應被回滾;

如果你在java中以編程方式執行它,你可以把更新放在try-catch塊中,並在try或catch結尾回滾。

+0

正如問題中所提到的,這些命令不是逐行執行,而不是從Java執行,而是使用'sqlite3'命令行shell。 –

+0

如何在sqlite命令行shell中執行它,如果它不是一行一行? – Juan

+0

在批處理模式下,從文件中。 –