MySQL 事務管理

2022-07-04 10:15:10 字數 3105 閱讀 7576

事務的4個特性(acid)

事務管理的相關命令

start transaction;  #開始事務

sql語句1;

sql語句2;

.....

commit; #提交事務

#rollback; #回滾

流程示例

start transaction;

insert into tb_user (name,age) values ('zhangsan',20);  #顯示query ok,這條sql語句可以成功執行

insert into tb_user (name,age) values ('李四','age');  #顯示error,發生錯誤。只是說這條語句執行錯誤,但後面還可以執行sql語句

insert into tb_user (name,age) values ('wangwu',20);  #顯示query ok,

如果此時commit;提交,會把執行成功的2個sql語句做的修改持久化資料庫,失敗的sql語句則忽略。

其實發生error時,為了做到事務的原子性,就應該rollback;回滾。

並不是說start transaction;  .....  commit;  會自動維持事務的4個特性,全部成功就持久化到資料庫,某些sql語句發生錯誤,就自動回滾,不是這樣的。

事務的4個特性需要我們自己來維持。

**中使用事務也一樣:

......   //開啟事務

trycatch(exception e)

先開啟事務,把要執行的多個sql語句放到try中,都正確執行那就提交,發生錯誤就回滾。

catch就是對異常的處理,既然捕獲了異常進行了處理,就不會往上一級拋了。

如果每一級都是throws往上拋,拋到jvm,jvm預設的異常處理方式是:列印異常資訊,終止程式執行。

比如說下面這段**:

system.out.println(1

);

trycatch

(exception e)

system.

out.println(2);

1

error

2

並不會自動在控制台列印異常資訊,終止程式。

要看異常資訊,可以在catch中 system.out.println(e.getmessage()); 列印出來

事務的併發即同時執行多個事務,主要涉及事務的隔離性、隔離級別。

1、事務併發執行可能出現的問題

(1)髒讀     乙個事務讀取其它事務尚未提交的資料

事務b對資料庫做了修改(執行成功但尚未提交),事務a讀取這些已修改的記錄,a讀取之後,b進行了回滾,a讀取到的資料變成了髒資料、無效資料,即髒讀。

隔離級別 read commited 已提交讀,可解決髒讀問題,等到使用這些記錄的事務提交後才讀取資料。

(2)不可重複讀     前後多次讀取,讀取的資料內容不一致(期間進行了update操作)

比如說我卡里有2000,打算在atm上取款2000,輸入取款金額2000點選確定,系統查詢賬戶餘額,還有2000,是夠的;

atm執行扣款-2000(在賬戶餘額的基礎上扣,money-2000,又要獲取賬戶餘額),並往外吐錢2000,1000-2000=-1000

atm前後2次讀取餘額(同一條記錄的資料),讀取的資料內容不一致,這就出現問題了。

隔離級別 repeatable read 重複讀,可解決不可重複讀的問題,當有事務讀了某些行的資料後,這些行會被鎖住,不允許其它事務對這些行進行修改,這樣重複讀取到的資料就是一致的。

因為使用某些行時,這些行會被鎖定,其它事務不能讀取這些(可能會被修改的)行,也避免了髒讀問題。

(3)幻讀(虛讀)   前後多次讀取,讀取的記錄數不一致(期間進行了insert、delete操作)

隔離級別 serializable 可解決幻讀問題,不允許事務併發,最安全,但效能最差,基本不用。

以上3個是讀問題,還可能產生乙個寫問題:丟失更新。

(4)丟失更新  丟失更新是不可重複讀中的一種特殊情況,2個事務都要修改記錄內容(update),後提交的覆蓋了前面提交的

時間取款事務

支票轉賬事務

t1開始事務

t2開始事務

t3查詢賬戶餘額為1000元

t4查詢賬戶餘額為1000元

t5取出100,把存款餘額改為900元

t6提交事務

t7匯入100元,把存款餘額改為1100元

t8提交事務

-100的更新操作丟失了。

2、4種隔離級別

一般折中選擇第2、3項,使用預設的即可,不必進行設定。

3、檢視、設定隔離級別

#mysql 

5 select @@tx_isolation; #檢視當前會話使用的隔離級別

select @@global.tx_isolation; #檢視全域性設定的隔離級別

#mysql 8

select @@transaction_isolation;

#檢視當前會話使用的隔離級別

select @@global.transaction_isolation; #檢視全域性設定的隔離級別

#mysql5、mysql8的檢視方式不同,5是tx,8是transaction,如果不對應會報錯unknown system variable 'tx_isolation'|'transaction_isolation'

#設定事務的隔離級別,5、8一樣

set session transaction isolation level repeatable read; #設定當期會話使用的隔離級別為repeatable read

set global transaction isolation level repeatable read; #設定全域性使用的隔離級別是repeatable read

如果我們沒有使用start transaction開啟事務,預設把一條sql語句(帶分號)作為乙個事務處理,會自動提交。

mysql事務管理

事務 由多個sql語句組成 這些sql作為乙個整體不可分割,如果其中一條sql不能執行,那麼整個單元會回滾,只有所有sql語句都成功執行才能說這個事務被成功的執行了 mysql的儲存引擎中innodb bdb支援事務 每個事務的處理都滿足acid屬性 1 原子性 事務被看成乙個不可分割的單元 2 一...

mysql 事務管理

事務管理 邏輯上的一組操作,要麼同時完成,要麼同時失敗。mysql start transaction 宣告乙個事務的開始 從a的賬戶向b的賬戶轉入100元 mysql update account setmoney money 100 where name a 步驟1,向a的賬戶存入100,mys...

mysql 事務管理(高階) 待續

請口述以下問題 什麼是事務到特性,具體說說你到理解 請舉乙個案例描述為什麼要用到事務 賬 事務的隔離級別 待續。a b a給b轉賬100 正常mysql流程 a賬戶b賬戶 a 100 b 100 可能情況 情況a賬戶b賬戶 第一種a 100 b 100 第二種a 100 b第三種 ab 100 第四...