在解釋 Isolation Level 隔離層級之前,先說明三個名詞 : 髒讀 (dirty read)、幻讀 (phantom read)、不可重複讀 (Non-Repeatable Read)。 髒讀 (dirty read) : 指在一個交易讀取到另一個尚未提交 (un-commit) 的交易資料。如果那個交易最終被回滾(Rollback),則讀到的資料就是不準確的,這就是所謂的「髒讀」。 髒讀就像做夢撿到錢,結果醒來什麼都沒有。 幻讀 (phantom read) : 指在一個交易中,當它多次執行同一查詢時,由於其他交易插入、更新或刪除了符合查詢條件的行,導致每次查詢返回的結果不同。 幻讀就像見到鬼,資料多了或是少了。 不可重複讀 (Non-Repeatable Read) : 指在一個交易在多次讀取同一筆資料時,該資料的值因為另一個交易的更新而發生變化。 不可重複讀就像碰到魔術師,明明手上是棍子,等一下 變成鴿子。 髒讀、幻讀、不可重複讀都不是正常的現象,除非有特別的目的,不然都應該盡量避免。 隔離層級是什麼? 隔離層級(Isolation Level)是資料庫管理系統中設定交易(Transaction)之間互相隔離程度的配置選項。它控制了在多個交易並發 (concur…
在之前的文章已經談過很多關於MySQL 資料庫鎖定 的觀念及實作,這篇把所有的觀念一次整合在一起,也比較容易完全理解MySQL的鎖定如何應用在實際的系統設計上。 鎖定的定義 : 在 MySQL 中,資料庫的鎖定是一種用於管理多用戶或程序同時訪問同一資料庫資源時的同步機制。鎖定可以幫助預防資料不一致和更新衝突,保護交易的完整性。 既然是鎖定,當然就會讓某一方等待,如果鎖得不好,就會發生死鎖 (deadlock)。 因此鎖定就是為了達成資料的一致性及完整性,犧牲某些效率的做法。你不可能既要資料的一致性及完整性,又要求任何連線都不能等待。在非常大量連線的情況下,這些等待都可能造成程式超時 (timeout) 。 例如php程式的預設超時 (default timeout) 是30秒,MySQL的預設鎖定等待超時 (lock wait timeout)是50秒,如果因為等待而超過,程式就會停止並顯示錯誤訊息。如果拉長預設超時,當遇到死鎖或是大家都在等待,就更可能吃光系統的資源,讓正在執行的更緩慢。 因此,多人連線的系統,正確的處理交易以及正確的使用鎖定是很重要的,並且正確性與效能是同樣重要的事情。 有些系統效能比正確性還重要 (例如臉書的數據處理),有些系統正確性比效能還重要 (例如銀…
什麼是交易(Transaction 很多人稱為事務)功能? 交易(或事務)指的是一連串的指令,並且把它們作為一個單一的工作單位執行。這些操作要嘛全部執行,要嘛全部取消。 交易主要用於保證資料的一致性和完整性,特別是在多用戶環境中,其中多個操作可能同時對相同的資料進行讀寫。 例如一個訂單的完成,包含「將庫存資料表的數量更新」,然後「將訂購的商品資料寫入訂單資料表」。 這兩個動作如果不是都完成,就會產生問題。例如庫存資料表的數量已經-1,但是訂單資料沒有寫入,那麼庫存數量就發生錯誤了;或是訂單資料已經寫入,但是庫存的數量-1發生錯誤,這樣也會發生資料一致性的問題。 例如以下的PHP程式 order.php : <?php include 'conn.inc.php' ; // 引入連線設定檔 // 從 myproducts 表抓取產品 $query = "SELECT pid, pname FROM myproducts" ; $result = $conn ->query( $query ); // 檢查訂購按鈕是否被點擊 if ( $_SERVER [ "REQUEST_METHOD" ] == &qu…