我真的不明白在并发数据访问的情况下等待的承诺。
所有手册均按期限锁定。没有人解释锁可能会导致 SQL 客户端在服务器端等待锁获取(并且可能需要几秒/分钟/无穷大)?
是否存在锁不会导致等待的情况?我能想象:
- 可能
READ UNCOMMITTED
在某些情况下,比如没有 DDL? - 不等就报错了...
- 没有人等待,但谁先
commit
获胜,其他人失败commit
我回顾了JDBC API:它从字面上提到:
SQLTimeoutException - 当驱动程序确定已超过setQueryTimeout方法指定的超时值并且至少尝试取消当前正在运行的语句时`
根据文档在客户端检测到超时。广泛使用的客户端 API对服务器端超时没有影响(包括由锁引起的)。可能您可以设置一些专有的连接属性来影响数据库行为。
我看到了一些专有的 SQL 扩展,例如:
- https://learn.microsoft.com/en-us/sql/t-sql/statements/set-lock-timeout-transact-sql
SET LOCK_TIMEOUT timeout_period
- https://www.postgresql.org/docs/13/runtime-config-client.html
set lock_timeout ms
&set statement_timeout ms
对我来说,由于锁而等待的数据库是一个灰色区域。锁定是否意味着等待?
在大多数情况下,锁不会导致等待。
想象一下,我有一个简单的银行系统。为了将资金从账户 A 转移到账户 B,我启动了一个事务并在两个账户记录上获取了行级锁。这让我可以运行我的验证(即 A 有足够的资金进行转账,欺诈部门在任何一个账户上都没有标记,等等),更新两个账户以反映新余额,生成所需的任何日志记录,然后提交无需担心其他会话已对一个或两个帐户进行了更改,而这本应阻止转移。
除非在我正在处理尝试锁定 A 或 B 的传输的几分之一秒内出现其他会话,否则我获得的锁不会产生任何等待。当然,另一个会话可能会在我的会话同时处理 A 的事务,因此需要锁定。但考虑到需要处理的数千个账户和数百万笔交易,锁的竞争不太可能发生。特别是如果我明智地设计系统,例如,特定帐户的所有批处理交易都由一个线程处理。如果没有争用,就没有等待。