【以轉賬為例】
事務
事務是指滿足ACID的一組操作,可以通過Commit提交一個事務,也可以使用Rollback進行回滾。
ACID
1.原子性(Atomicity)
事務被視為不可分割的最小單元,事務的所有操作要么全部提交成功,要么全部失敗回滾。
2.一致性(Consisitency)
數據庫在事務執行前后都保持一致性狀態。即轉賬前后,兩個人賬戶總金額不變。
3.隔離性(Isolation)
根據隔離級別,一個事物所作的修改對於其他事務來說是不確定的。
4.持久性(Durability)
一旦事務提交,則其所作的修改將會永遠保存到數據庫中。
隔離級別
mysql默認的隔離級別是可重復讀。
下面的代碼所運行的兩個事務需要在兩個不同的session中執行,開啟兩個客戶端。
1.讀未提交 READ UNCOMMITTED
讀未提交:事務中的修改,即使沒有提交,對其他事務也是可見的。
事務1:
1 set session transaction isolation level read uncommitted; 2 3 start transaction; 4 update user set money = money - 100 where id = 1; 5 update user set money = money + 100 where id = 2; 6 commit;
事務2:
1 set session transaction isolation level read uncommitted; 2 3 start transaction; 4 select * from user; 5 commit;
同時開啟事務1、事務2。事務2執行到第4行查看兩人賬戶余額都為100,當事務1執行到第4行,事務2再執行第4行查詢操作,可以看到id為1的人賬戶余額少了100,由此可見事務2在執行過程中可以查看到事務1執行但尚未提交的sql。
2.讀已提交 READ COMMITTED
讀已提交:
事務1:正在執行中的事務可以讀取到其他已提交事務所做的修改。
1 set session transaction isolation level read committed; 2 3 start transaction; 4 update user set money = money - 100 where id = 1; 5 update user set money = money + 100 where id = 2; 6 commit;
事務2:
1 set session transaction isolation level read committed; 2 3 start transaction; 4 select * from user; 5 commit;
同時開啟事務1、事務2。事務2執行到第4行查看兩人賬戶余額都為100,當事務1執行到第4行,事務2再執行第4行查詢操作,可以看到兩人賬戶中的余額沒有改變,由此可見事務2在執行過程中不能查看到事務1執行但尚未提交的sql,即只能讀已經提交的事務。
3.可重復讀 REPEATABLE READ
可重復度:保證在同一事務中多次讀取同樣數據的結果是一樣的,即正在執行中的事務不能讀取到其他已提交事務所做的修改。
事務1:
1 set session transaction isolation level repeatable read; 2 3 start transaction; 4 update user set money = money - 100 where id = 1; 5 update user set money = money + 100 where id = 2; 6 commit;
事務2:
1 set session transaction isolation level repeatable read; 2 3 start transaction; 4 select * from user; 5 commit;
同時開啟事務1、事務2。事務2執行到第4行查看兩人賬戶余額都為100,當事務1執行到第4行,事務2再執行第4行查詢操作,可以看到兩人賬戶中的余額沒有改變,繼續執行完事務1,事務1已經提交,此時執行事務2的第4行,發現兩人賬戶中的余額依然分別為100,但在事務1的客戶端中查詢發現轉賬已經完成,此時我們提交事務2,然后在事務2的客戶端中再次執行查詢,此時發現已經轉賬完成。由此可見事務2在執行過程中不能查看到事務1執行且已經提交的sql,即在事務1過程中,可以重復讀取到相同且為改變的值。
4.串行化 SERIALIZABLE
串行化:強制事務串行執行。
