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
,或在某些交易隔離層級中讀取資料。一致性讀取會忽略讀取檢視中存在的記錄上設定的任何鎖定。記錄的舊版本無法鎖定;它們是透過在記錄的記憶體內複製上套用復原記錄來重建的。鎖定會在其所取得的交易存在期間保留。除非交易開啟或自動提交模式關閉,否則會在陳述式完成後立即釋放它們。
兩種鎖定方法都支援 NOWAIT
和 SKIP LOCKED
InnoDB
鎖定模式。如需詳細資訊,請參閱 使用 NOWAIT 和 SKIP LOCKED 鎖定讀取並行。若要使用這些鎖定模式搭配鎖定方法,請傳入下列其中一個
NOWAIT
- 如果函數遇到資料列鎖定,它會中止並產生ER_LOCK_NOWAIT
錯誤SKIP_LOCKED
- 如果函數遇到資料列鎖定,它會跳過資料列並繼續DEFAULT
- 如果函數遇到資料列鎖定,它會等到沒有鎖定。相當於呼叫沒有模式的鎖定方法。
使用鎖定模式時,請注意下列事項
autocommit
模式表示永遠有一個交易開啟,該交易會在 SQL 陳述式執行時自動提交。預設情況下,工作階段處於自動提交模式。
當您呼叫
startTransaction()
時,您會隱含地停用自動提交模式。在自動提交模式下,如果取得鎖定,則會在陳述式完成後釋放。這可能會讓您認為鎖定未取得,但事實並非如此。
同樣地,如果您嘗試取得其他人已經擁有的鎖定,則陳述式會封鎖,直到其他鎖定釋放為止。