關於事務 — 備忘

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

事務的四個屬性:原子性(atomicity)、一致性(consistency)、隔離性(isolation)和永續性(durability)

PROPAGATION_REQUIRED      — 支援當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。

PROPAGATION_SUPPORTS      — 支援當前事務,如果當前沒有事務,就以非事務方式執行。

PROPAGATION_MANDATORY     — 支援當前事務,如果當前沒有事務,就丟擲異常。

PROPAGATION_REQUIRES_NEW  — 新建事務,如果當前存在事務,就把當前事務掛起。

PROPAGATION_NOT_SUPPORTED — 以非事務方式執行,如果當前存在事務,就把當前事務掛起。

PROPAGATION_NEVER         — 以非事務方式執行,如果當前存在事務,就丟擲異常。

PROPAGATION_NESTED        — 如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則進行與 PROPAGATION_REQUIRED 類似的操作。

前六個策略類似於 EJB CMT,第七個(PROPAGATION_NESTED)是 Spring 所提供的一個特殊變數。

它要求事務管理器或者使用 JDBC 3.0 Savepoint API 提供巢狀事務行為(如 Spring 的 DataSourceTransactionManager)

資料庫併發操作存在的異常情況:

髒讀(Dirty Reads): 一個事務開始讀取了某行資料但是另外一個事務已經更新了此資料但沒有能夠及時提交。

不可重複讀(Non-repeatable Reads): 一個事務對同一行資料重複讀取兩次但是卻得到了不同結果。例如在兩次讀取中有另外一個事務對該行資料進行了修改並提交

幻讀(Phantom Reads): 事務在操作過程中進行兩次查詢,第二次查詢結果包含了第一次查詢中未出現的資料, 這是因為在兩次查詢過程中有另外一個事務插入資料造成的

為避免上面出現幾種情況在標準 SQL 規範中定義了 4 個事務隔離級別,不同隔離級別對事務處理不同:

隔離級別                      髒讀取 重複讀取 幻讀 

未授權讀取(Read Uncommitted)  Y      Y        Y

授權讀取(Read Committed)      N      Y        Y

可重複讀取(Repeatable Read)   N      N        Y

序列(Serializable)            N      N        N

在資料庫中有兩種基本的鎖型別:

排它鎖(eXclusive Locks,即 X 鎖)

    當資料物件被加上排它鎖時,其他的事務不能對它讀取和修改。

共享鎖(Share Locks,即 S 鎖)

    當資料物件被加上共享鎖時,可以被其他事務讀取,但不能修改。資料庫利用這兩種基本的鎖型別來對資料庫的事務進行併發控制。

從程式的角度看, 鎖分為以下兩種型別:

樂觀鎖(Optimistic Lock)

    樂觀鎖假定在處理資料時,不需要在應用程式的程式碼中做任何事情就可以直接在記錄上加鎖、即完全依靠資料庫來管理鎖的工作。一般情況下,當執行事務處理時資料庫會自動對事務處理範圍內更新到的表做鎖定。 

悲觀鎖(Pessimistic Lock)

    悲觀鎖對資料庫系統的自動管理不感冒,需要程式設計師直接管理資料或物件上的加鎖處理,並負責獲取、共享和放棄正在使用的資料上的任何鎖。

* 事務是有代價的,不是所有系統都弄個事務。這是個仁者見仁智者見智的問題,比如 OSC 就沒弄這玩意,上次聚會聽紅薯說的,我覺得很對。具體問題具體分析嘛。


(adsbygoogle = window.adsbygoogle || []).push({});

function googleAdJSAtOnload() {
var element = document.createElement(“script”);
element.src = “//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js”;
element.async = true;
document.body.appendChild(element);
}
if (window.addEventListener) {
window.addEventListener(“load”, googleAdJSAtOnload, false);
} else if (window.attachEvent) {
window.attachEvent(“onload”, googleAdJSAtOnload);
} else {
window.onload = googleAdJSAtOnload;
}

資料庫 最新文章