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()
時,您會隱式停用自動認可模式。在自動認可模式下,如果獲得鎖定,它會在陳述式完成後釋放。這可能會讓您得出鎖定未獲得的結論,但事實並非如此。
同樣地,如果您嘗試獲得其他人已擁有的鎖定,陳述式會封鎖,直到其他鎖定釋放為止。