X DevAPI 透過 Collection.find() 和 Table.select() 方法的 lockShared()
和 lockExclusive()
方法來支援 MySQL 鎖定。這讓您能夠控制資料列鎖定,以確保在集合上進行安全、交易的文件更新,並避免並行問題,例如在使用 modify() 方法時。本節說明如何針對 Collection.find() 和 Table.select() 方法使用 lockShared()
和 lockExclusive()
方法。如需關於鎖定的更多背景資訊,請參閱鎖定讀取。
lockShared()
和 lockExclusive()
方法具有下列屬性,無論其是與 Collection 或 Table 一起使用。
允許多次呼叫鎖定方法。如果某個鎖定陳述式在不同的交易持有相同的鎖定時執行,則會封鎖直到其他交易釋放鎖定為止。如果多次呼叫鎖定方法,則最後呼叫的鎖定方法優先。換句話說,
find().lockShared().lockExclusive()
等同於find().lockExclusive()
。lockShared()
具有與SELECT ... LOCK IN SHARE MODE
相同的語意。在任何讀取的資料列上設定共用模式鎖定。其他工作階段可以讀取這些資料列,但無法修改它們,直到您的交易認可為止。如果這些資料列中的任何資料列已由尚未認可的其他交易變更,您的查詢會等待直到該交易結束,然後使用最新的值。lockExclusive()
具有與SELECT ... FOR UPDATE
相同的語意。對於搜尋遇到的任何索引記錄,它會鎖定資料列和任何相關聯的索引項目,如同您針對這些資料列發出UPDATE
陳述式一樣。其他交易會遭到封鎖而無法更新這些資料列、無法執行SELECT ... LOCK IN SHARE MODE
,或無法在某些交易隔離層級中讀取資料。一致性讀取會忽略在讀取檢視中存在的記錄上設定的任何鎖定。無法鎖定記錄的舊版本;它們是藉由在記錄的記憶體內複本上套用復原記錄來重建。鎖定會保留在取得鎖定的交易存在期間。除非交易開啟或 autocommit 模式關閉,否則它們會在陳述式完成後立即釋放。
兩種鎖定方法都支援 NOWAIT
和 SKIP LOCKED
InnoDB
鎖定模式。如需更多資訊,請參閱使用 NOWAIT 和 SKIP LOCKED 的鎖定讀取並行。若要搭配鎖定方法使用這些鎖定模式,請傳入下列其中之一
NOWAIT
- 如果函數遇到資料列鎖定,它會中止並產生ER_LOCK_NOWAIT
錯誤SKIP_LOCKED
- 如果函數遇到資料列鎖定,它會跳過資料列並繼續DEFAULT
- 如果函數遇到資料列鎖定,它會等待直到沒有鎖定為止。這等同於呼叫不含模式的鎖定方法。
使用鎖定模式時,請注意下列事項
autocommit
模式表示一律會有一個交易開啟,此交易會在執行 SQL 陳述式時自動認可。根據預設,工作階段會處於 autocommit 模式。
當您呼叫
startTransaction()
時,會隱含地停用 autocommit 模式。在 autocommit 模式中,如果取得鎖定,則會在陳述式完成後釋放鎖定。這可能會讓您得出鎖定未取得的結論,但事實並非如此。
同樣地,如果您嘗試取得其他人已擁有的鎖定,則陳述式會封鎖,直到其他鎖定釋放為止。