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()
时,您会隐式地禁用自动提交模式。在自动提交模式下,如果获取了锁,它将在语句完成后释放。这可能会让您得出没有获取锁定的结论,但事实并非如此。
类似地,如果您尝试获取其他人已经拥有的锁定,该语句将阻塞,直到其他锁定被释放。