X DevAPI 通过 lockShared()
和 lockExclusive()
方法支持 MySQL 锁定,这些方法适用于 Collection.find() 和 Table.select() 方法。这使您能够控制行锁定以确保对集合的安全、事务性文档更新,并避免并发问题,例如在使用 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
或在某些事务隔离级别下读取数据。一致性读取会忽略对读取视图中存在的记录设置的任何锁定。无法锁定记录的旧版本;它们是通过将撤销日志应用于记录的内存副本而重建的。锁定在获取它们的交易存在期间一直保持。它们在语句完成后立即释放,除非交易处于打开状态或自动提交模式已关闭。
两种锁定方法都支持 NOWAIT
和 SKIP LOCKED
InnoDB
锁定模式。有关更多信息,请参见 使用 NOWAIT 和 SKIP LOCKED 进行锁定读取并发。要将这些锁定模式与锁定方法一起使用,请传入以下之一
NOWAIT
- 如果函数遇到行锁定,它将中止并生成ER_LOCK_NOWAIT
错误SKIP_LOCKED
- 如果函数遇到行锁定,它将跳过该行并继续DEFAULT
- 如果函数遇到行锁定,它将等待,直到没有锁定。等效于在没有模式的情况下调用锁定方法。
使用锁定模式时,请注意以下事项
autocommit
模式意味着始终存在一个交易,该交易在 SQL 语句执行时会自动提交。默认情况下,会话处于自动提交模式。
在调用
startTransaction()
时,会隐式禁用自动提交模式。在自动提交模式下,如果获取了锁定,则在语句完成后会释放该锁定。这可能会导致您得出结论认为没有获取锁定,但实际上并非如此。
同样,如果您尝试获取已被其他人拥有的锁定,则该语句将阻塞,直到其他锁定被释放。