在之前的文章已經談過很多關於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…
什麼是鎖定 (Lock)? MySQL 中的鎖定(Lock)是資料庫管理系統中的一種機制,用於確保資料的一致性和並行控制 (Concurrency Control)。
I 、基本觀念 問題:什麼是 Lock (鎖定) ? 答案:Lock 的主要目的是避免資料發生錯誤,把不應該進行動作的指令排除在外,並讓應該進行動作的指令能夠順利完成。 問題:什麼是Table Lock (表單鎖定) ? 什麼是Row Lock (紀錄鎖定)? 答案:表單鎖定就是將整個資料表鎖定,讓其他連線無法讀取及異動,直到資料處理完畢為止。紀錄鎖定就是將指定的紀錄鎖定,讓其他連線無法讀取及異動,直到資料處理完畢為止。 問題:InnoDB與MyISAM的鎖定有何差別? 答案:MyISAM 沒有交易功能 (Transaction),若要避免多個連線交互執行 SQL 指令,造成資料錯亂,只好使用鎖定資料表 (Table Lock) 的方式,InnoDB則可以使用Table Lock 與Row Lock。 問題:MySQL不同版本的鎖定有何差別? 答案:MySQL不同版本的鎖定原理一樣,只是語法上有些差異。 例如 : MySQL 5.5 使用 Select ... lock in share mode; MySQL 5.5 使用 Select ... for update; MySQL 8.0 還可以使用 Select ... for share…