下載本手冊

8.3 使用鎖定

X DevAPI 透過 Collection.find() 和 Table.select() 方法的 lockShared()lockExclusive() 方法支援 MySQL 鎖定。這讓您能夠控制資料列鎖定,以確保集合上的安全、交易性文件更新,並避免並行問題,例如在使用 modify() 方法時。本節描述如何針對 Collection.find() 和 Table.select() 方法使用 lockShared()lockExclusive() 方法。如需有關鎖定的更多背景資訊,請參閱鎖定讀取

無論 lockShared()lockExclusive() 方法用於集合或資料表,它們都具有下列屬性。

  • 允許多次呼叫鎖定方法。如果鎖定陳述式執行時,不同的交易持有相同的鎖定,它會封鎖,直到其他交易釋放鎖定為止。如果多次呼叫鎖定方法,則最後呼叫的鎖定方法優先。換句話說,find().lockShared().lockExclusive() 等同於 find().lockExclusive()

  • lockShared() 具有與 SELECT ... LOCK IN SHARE MODE 相同的語意。在讀取的任何資料列上設定共用模式鎖定。其他工作階段可以讀取資料列,但在您的交易認可之前,無法修改它們。如果這些資料列的任何一個被另一個尚未認可的交易變更,您的查詢會等到該交易結束,然後使用最新的值。

  • lockExclusive() 具有與 SELECT ... FOR UPDATE 相同的語意。對於搜尋遇到的任何索引記錄,它會鎖定資料列和任何相關聯的索引項目,其方式與您針對這些資料列發出 UPDATE 陳述式的方式相同。其他交易會被封鎖而無法更新這些資料列、無法執行 SELECT ... LOCK IN SHARE MODE,或無法在某些交易隔離層級中讀取資料。一致讀取會忽略在讀取視圖中存在的記錄上設定的任何鎖定。無法鎖定記錄的舊版本;它們是透過在記錄的記憶體內部副本上套用復原記錄來重建的。

  • 鎖定會在其獲得的交易存在期間內保持。除非交易開啟或自動認可模式關閉,否則它們會在陳述式完成後立即釋放。

這兩種鎖定方法都支援 NOWAITSKIP LOCKED InnoDB 鎖定模式。如需更多資訊,請參閱 使用 NOWAIT 和 SKIP LOCKED 的鎖定讀取並行。若要搭配鎖定方法使用這些鎖定模式,請傳入下列其中一個

  • NOWAIT - 如果函數遇到資料列鎖定,它會中止並產生 ER_LOCK_NOWAIT 錯誤

  • SKIP_LOCKED - 如果函數遇到資料列鎖定,它會跳過該資料列並繼續

  • DEFAULT - 如果函數遇到資料列鎖定,它會等到沒有鎖定。相當於呼叫沒有模式的鎖定方法。

鎖定考量

使用鎖定模式時,請注意下列事項

  • autocommit 模式表示永遠有一個交易開啟,該交易會在 SQL 陳述式執行時自動認可。

  • 依預設,工作階段處於自動認可模式。

  • 當您呼叫 startTransaction() 時,您會隱式停用自動認可模式。

  • 在自動認可模式下,如果獲得鎖定,它會在陳述式完成後釋放。這可能會讓您得出鎖定未獲得的結論,但事實並非如此。

  • 同樣地,如果您嘗試獲得其他人已擁有的鎖定,陳述式會封鎖,直到其他鎖定釋放為止。