ACDI事物的四大特性

ACDI事物的四大特性


  • 原子性(Atomicity)
    原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
    比如:轉賬轉過去的加和轉時候的減必須一次發生
  • 一致性(Consistency)
    事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。
    比如:轉賬時雙方的總數在轉賬的時候保持一致
  • 隔離性(Isolation)
    事務的隔離性是多個用戶併發訪問數據庫時,數據庫爲每一個用戶開啓的事務,不能被其他事務的操作數據所幹擾,多個併發事務之間要相互隔離。
    比如:多個用戶操縱,防止數據干擾,就要爲每個客戶開啓一個自己的事務;
  • 持久性(Durability)
    持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即使數據庫發生故障也不應該對其有任何影響。
    比如:如果我commit提交後 無論發生什麼都 都不會影響到我提交的數據;

數據庫開啓事務命令


  1. start transaction 開啓事務
  2. Rollback 回滾事務
  3. Commit 提交事務

當Jdbc程序向數據庫獲得一個Connection對象時,默認情況下這個Connection對象會自動向數據庫提交在它上面發送的SQL語句。若想關閉這種默認提交方式,讓多條SQL在一個事務中執行,可使用下列語句:
JDBC控制事務語句

Connection.setAutoCommit(false);如同數據庫開啓命令的 start transaction
Connection.rollback(); == rollback
Connection.commit();  == commit

設置事務回滾點

Savepoint sp = conn.setSavepoint();
Conn.rollback(sp);
Conn.commit();   //回滾後必須要提交

數據庫共定義了四種隔離級別:
Serializable:可避免髒讀、不可重複讀、虛讀情況的發生。(串行化)
Repeatable read:可避免髒讀、不可重複讀情況的發生。(可重複讀)
Read committed:可避免髒讀情況發生(讀已提交)。
Read uncommitted:最低級別,以上情況均無法保證。(讀未提交)
set transaction isolation level 設置事務隔離級別
select @@tx_isolation 查詢當前事務隔離級別


演示不同隔離級別下的併發問題


1.當把事務的隔離級別設置爲read uncommitted時,會引發髒讀、不可重複讀和虛讀

A窗口
set transaction isolation level  read uncommitted;
start transaction;
select * from account;
-----發現a帳戶是1000元,轉到b窗口
select * from account
-----發現a多了100元,這時候a讀到了b未提交的數據(髒讀)

B窗口
start transaction;
update account set money=money+100 where name='aaa';
-----不要提交,轉到a窗口查詢

2.當把事務的隔離級別設置爲read committed時,會引發不可重複讀和虛讀,但避免了髒讀

A窗口
set transaction isolation level  read committed;
start transaction;
select * from account;
-----發現a帳戶是1000元,轉到b窗口
select * from account;
-----發現a帳戶多了100,這時候,a讀到了別的事務提交的數據,兩次讀取a帳戶讀到的是不同的結果(不可重複讀)


B窗口
start transaction;
update account set money=money+100 where name='aaa';
commit;
-----轉到a窗口

3.當把事務的隔離級別設置爲repeatable read(mysql默認級別)時,會引發虛讀,但避免了髒讀、不可重複讀

A窗口
set transaction isolation level repeatable read;
start transaction;
select * from account;
----發現表有4個記錄,轉到b窗口
select * from account;
----可能發現表有5條記如,這時候發生了a讀取到另外一個事務插入的數據(虛讀)


B窗口
start transaction;
insert into account(name,money) values('ggg',1000);
commit;
-----轉到 a窗口

4.當把事務的隔離級別設置爲Serializable時,會避免所有問題

A窗口
set transaction isolation level Serializable;
start transaction;
select * from account;
-----轉到b窗口

B窗口
start transaction;
insert into account(name,money) values('ggg',1000);
-----發現不能插入,只能等待a結束事務才能插入
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章