1. 程式人生 > >小談事務

小談事務

工作 你在 如果 鎖機制 什麽 com 方式 基礎 之間

1.事務是什麽?

並發控制單位,該工作單元內的操作是不可分割的。

2.為什麽要使用事務?

高並發環境下,沒有一定限制地並發對數據進行操作是不安全的,使用事務可以從某種程度上保障這種“安全”。

3.事務的特性

原子性(Atomicity) :

事務是數據庫的邏輯工作單位,事務中包含的各操作要麽都做,要麽都不做 。

隔離性(Isolation) :

一個事務的執行不能其它事務幹擾。一個事務內部的操作及使用的數據對其它並發事務是隔離的,並發執行的各個事務之間不能互相幹擾,隔離是有程度的,不同的隔離級別也修飾了不同的一致性。

持續性(Durability) :

持續性也稱永久性,是指一個事務一旦提交,它對數據庫中的數據的改變就應該是永久性的。接下來的其它操作或故障不應該對其執行結果有任何影響。

一致性(Consistency) :

事務執行的結果必須是使數據庫從一個一致性狀態變到另一個一致性狀態。該狀態由原子性、持久性保證、由鎖操作支持,由隔離性修飾。

解釋:

1.當數據庫只包含成功事務提交的結果時,就說數據庫處於一致性狀態。假如數據庫系統運行中發生故障,有些事務尚未完成就被迫中斷,這些未完成事務對數據庫所做的修改有一部分已寫入物理數據庫,這時數據庫就處於一種不一致的狀態。那麽這個部分顯然是由原子性隔離性保證的,保證了物理上的一致性。

2.所有的事務本質也是一段執行邏輯,不同的邏輯對應的也是不同的一致性要求,同時也會有不同的問題。這個部分為了避免問題,就需要通過設置不同的隔離級別,去修飾一致性。而這個部分一般是由數據庫的鎖機制

實現的,這部分保證的是事務的邏輯一致性。

4.事務並發問題

1.臟讀

2.不可重復讀

3.幻讀

4.第一類丟失更新(回滾丟失)

5.第二類丟失更新(修改丟失)

Mysql的數據庫默認隔離級別為Committed Read,不能避免不可重復讀和第二類丟失更新的問題。要解決這個問題需要采用悲觀鎖、樂觀鎖避免

5.第二類丟失更新解決方案

悲觀鎖

(推薦)在修改數據時先查詢下,當然這個查詢必須也要加鎖(select ...for update nowait),在這裏不加for update就不能保證你在查詢到更新提交這段時間裏這條記錄沒有被其他會話更新過,所以這種方式也需要在查詢時鎖定記錄,保證在這條記錄沒有變化的基礎上再做更新,若有變化則提示告知用戶。

樂觀鎖

a.舊值法:

就是在sql更新時使用舊的狀態值做條件,SQL大致如下 Update table set col1 = newcol1value, col2 = newcol2value…. where col1 = oldcol1value and col2 = oldcol2value….,如果這條記錄已經被其他會話更新過,則本次更新了0行,這裏我們應用系統一般會做個提示告知用戶重新查詢更新。這個取哪些舊值作為條件更新視具體系統實際情況而定。(這種方式有可能發生阻塞,如果應用其他地方使用悲觀鎖法長時間鎖定了這條記錄,則本次會話就需要等待,所以使用這種方式時最好統一使用樂觀鎖法。)

b.版本列法:

(推薦)其實這種方式是一個特殊化的前鏡像法,就是不需要使用多個舊值做條件,只需要在表上加一個版本列,這一列可以是NUMBER或 DATE/TIMESTAMP列,加這列的作用就是用來記錄這條數據的版本(在表設計時一般我們都會給每個表增加一些NUMBER型和DATE型的冗余字段,以便擴展使用,這些冗余字段完全可以作為版本列用),在應用程序中我們每次操作對版本列做維護即可。在更新時我們把上次版本作為條件進行更新。

小談事務