1. 程式人生 > >事務(以MySQL為例)

事務(以MySQL為例)

事務指邏輯上對資料庫的一組操作,事務有以下四大特性:

1.原子性:事務的一組操作捆綁在一起,要麼全都執行,要麼都不執行
2.一致性:事務的完成使資料庫從一致性狀態轉到一致性狀態,一致性也就是指資料的正確性或者穩定的一種狀態,例如A給B轉賬的操作中,A的餘額減少但B的餘額還未增多的時刻,此時資料庫就沒有處於一致性的狀態
3.隔離性:多個併發事務之間要相互隔離,不能產生干擾
4.永續性:事務一旦被提交,資料庫就會同步更新,它帶來的影響就是永久性的

事務命令

1.開啟事務:start transaction
2.事務回滾:rollback
3.提交事務:commit
在start transaction和commit之間的操作屬於一個事務,在提交之前,如果發生了異常,資料庫會自動回滾,也可以手動rollback

JDBC使用事務

1.開啟事務:Connection.setAutoCommit(false);
2.事務回滾:Connection.rollback();
3.提交事務:Connection.commit();
注意有時我們不需要回滾整個事務,而是回滾部分事務,所以要設定事務回滾點:

操作1...
Savepoint sp = conn.setSavepoint();
操作2...
Conn.rollback(sp);
Conn.commit(); // 回滾後必須通知資料庫提交事務

其中操作2會被回滾掉,操作1會儲存下來然後被提交

事務的隔離級別

首先如果不隔離,會出現以下三種情況:
1.髒讀:你讀取到了其他事務已經修改但還未提交的資料(注意雖然未提交但資料庫中的記錄也是會改變的,只是提交之後這種操作就被完全持久化,無法通過回滾來消除)
2.不可重複讀:在一個事務中,你前後兩次讀到的同一個資料的值不同,因為有其他事務對其進行了修改
3.幻讀:在一個事務中,你對某一批資料整體進行了操作,但由於在這批資料之外有其他事務修改了資料,也可能會造成操作結果的不合理,例如你在將所有資料的狀態更新為1的同時,其他事務插入了一條狀態為0的資料,最後你看到的結果並不是所有資料狀態都為1

加鎖策略:
1.避免髒讀:修改資料時加排它鎖,事務提交之後釋放鎖
2.避免不可重複讀:讀資料時加共享鎖,事務提交之後釋放鎖,當所有共享鎖都釋放時才可進行資料的修改
3.避免幻讀:加範圍鎖,它是共享鎖,整張表都不允許修改資料

MySQL有四種隔離級別可設定:
1.Serializable(序列化):可避免髒讀、不可重複讀、幻讀情況的發生
2.Repeatable Read(可重複讀):可避免髒讀、不可重複讀情況的發生
3.Read Committed(讀已提交):可避免髒讀情況發生
4.Read Uncommitted(讀未提交):最低級別,以上情況均無法保證
MySQL預設隔離級別為Repeatable Read

設定方法:
1.全域性設定
修改my.ini檔案

可選引數有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.

[mysqld]
transaction-isolation = REPEATABLE-READ

2.登入mysql後對當前session進行修改

set session transaction isolation level read uncommitted; // 設定當前事務隔離級別