最近要對資料庫的資料進行乙個定時遷移,為了防止在執行過程sql語句因為某些原因報錯而導致資料轉移混亂,因此要對我們的指令碼加以事務進行控制。
首先我們建一張tran_test表
create table tran_test(
f1 varchar(10) not null,
f2 int(1) default null,
primary key (f1)
)engine=innodb charset=utf8
我想對tran_test插入兩條資料,但是為了防止插入中報錯,因此我要把插入語句控制在乙個事務內。
這時候,如果你查一下有些人的文章,許多時候會給出你這麼一條答案。
start transaction;
insert into tran_test values('a',1);
insert into tran_test values('b',2);
rollback;
或
start transaction;
insert into tran_test values('a',1);
insert into tran_test values('b',2);
commit;
看上去很簡單的sql語句,並且這兩句也確實能實現提交或回滾。
然而這真的能達到我們的目的嗎?答案是否定的。
比如第一段,它是將你在事務中的sql語句無論對錯全部進行rollback。這樣絕對的回滾使得你的sql沒有任何意義了。
因此我們想要真正的控制好事務,我的思路是對要執行的sql進行異常檢測。如果sql沒有出現異常,commit,如果捕獲到了異常,則rollback。
這時候,我們就需要建乙個儲存過程來捕獲異常。執行成功時進行commit,sql執行失敗時則進行rollback。
兩種思路可以達到我想要的效果。
第一種是對我們要執行的sql進行異常捕獲,我們再定義乙個變數t_error,當捕獲到異常的時候,讓t_error=1。再對t_error進行條件判斷,如果t_error=1則進行rollback,否則進行commit。
drop procedure if exists t_test;
delimiter //
create procedure t_test()
begin
declare t_error integer;
declare continue handler for sqlexception set t_error = 1;
start transaction;
insert into tran_test values('a',1);
insert into tran_test values('b',2);
if t_error = 1 then
rollback;
else
commit;
end if;
end//
call t_test();
另乙隻則是第一種的簡化,即捕獲到異常直接進行rollback,如果沒捕獲到異常,直接commit
drop procedure if exists t_test;
delimiter //
create procedure t_test()
begin
declare exit handler for sqlexception rollback;
start transaction;
insert into tran_test values('a',1);
insert into tran_test values('b',2);
commit;
end//
call t_test()
這樣,這兩個insert語句便真正的被控制在了乙個事務內了。 spring事物的提交與回滾
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 註解方式宣告事務,該事務宣告的範圍是service中的方法,而一般的事務宣告時不是宣告在 業務邏輯方法上的,...
提交事務和回滾事務
9.5 提交事務和回滾事務 提交事務 commit 語句 事務 transaction 測試一下,在mysql中預設的事務行為是怎樣的 mysql預設情況下支援自動提交事務。實際上不符合開發習慣,為了保證資料安全,必須保證同時成功之後再提交 自動提交 每執行一條語句執行一次 怎麼將mysql的自動提...
事務的開啟回滾 提交
mysql use chapter06 database changed mysql create table account id int primary key auto increment,name varchar 40 money float engine innodb query ok,0...