2017年3月24日 星期五

Transaction( 事務 )

Transaction(事務)的概念:

  • 事務指邏輯上的一組操作,組成這組操作的各單元要就全部成功,要就全部不成功。
  • 資料庫如果沒有自己去控制事務,那預設是一條sql就處於在自己單獨的事物當中。
  • start transaction 為開啟事務,在這條sql語句之後的sql都將處於一個事務中,這些sql語句並不會立即執行
  • commit; 為提交事務,一旦提交,事務中所有的sql才會執行。
  • rollback; 回滾事務,將之前的所有事務取消。
例如:A與B轉帳對應的sql語句
  • update account set money=money-100 where name='A';
  • update account set money=money+100 where name='B';
JDBC中
  • Connection#setAutoCommit(false); // 相當於start transaction
  • Connection#rollback();                     // 相當於rollback
  • Connection#commit();                      // 相當於commit
事務的特性(ACID)
  • 原子性(Atomicity):一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
  • 一致性(Consistency):在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續資料庫可以自發性地完成預定的工作。
  • 隔離性(Isolation):資料庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)。
  • 持久性(Durability):事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。
事務隔離性導致的問題:

  1. 髒讀:當一個事務允許讀取另外一個事務修改但未提交的數據時,就可能發生髒讀。例如,當一個事務A正在讀取資料並且對資料進行了修改,而這種修改還沒提交到資料庫中這時另一個事務B也訪問了這個資料
  2. 不可重複讀:在一次事務中,當一行數據獲取兩遍得到不同的結果表示發生了「不可重複讀」。例如,在一個事務A中多次讀取同一筆資料,在事務A還未結束時,另一個事務B也訪問了這個資料,並且修改這個資料並且commit,那麼事務A在多次讀取這筆資料時可能會讀到不同的資料。
  3. 幻讀:在事務執行過程中,當兩個完全相同的查詢語句執行得到不同的結果集。這種現象稱為「幻讀(phantom read)」。例如:
               目前工資為1000的員工有10人。
                      1.事務A,讀取所有工資為1000的員工。
                        2.這時事務B向employee表插入了一條員工記錄,工資也為1000
                          3.事務B再次讀取所有工資為1000的員工 共讀取到了11條記錄。
        不可重複讀的重點是修改
                        同樣的條件, 你讀取過的數據,再次讀取出來發現值不一樣了
        幻讀的重點在於新增或者刪除
                        同樣的條件, 第 1 次和第 2 次讀出來的記錄數不一

        隔離級別 髒讀 不可重複讀 幻影讀
        未提交讀 可能發生 可能發生 可能發生
        提交讀        - 可能發生 可能發生
        可重複讀        -         - 可能發生
        可序列化         -        -        - 


        沒有留言:

        張貼留言