并发确认
库存变成负数的“丢失更新”问题,根源是什么?
- UPDATE 语句的 SQL 语法错误
- 库存列没有索引
- 读取、判断和写入之间可能被其他事务插入
- 没有提交事务
如果条件允许,成本最低的解决办法是什么?
- select ... for update
- 用一条语句完成(update ... where qty > 0)
- 锁定整张表
- 使用可串行化隔离级别
哪条规则能消除大多数死锁?
- 让所有事务按相同顺序获取锁
- 延长事务持续时间
- 降低隔离级别
- 增加索引
如果不设置 lock_timeout,最终往往是哪一部分先卡住?
- 数据库先停止工作
- 磁盘先被占满
- 网络带宽先被耗尽
- 连接池耗尽,导致应用程序停止响应
for update skip locked 改变了什么?
- 不再获取锁
- 不等待已锁定的行,而是跳过它们
- 自动提交事务
- 提高隔离级别
为什么不应在事务内部调用外部 API?
- 事务内部在语法上不允许这样做
- 调用外部服务后就无法提交
- 已获取的锁会在等待外部调用期间一直保持
- 因为响应会变慢
使用咨询锁时,需要特别注意什么?
- 它比普通锁慢
- 它只能在事务内部使用
- 目标表必须有索引
- 键空间是全局的,而且会话级锁必须在归还连接前释放
如何用一行结果查看阻塞关系?
- 在 pg_stat_activity 中查看 pg_blocking_pids(pid)
- 直接将 pg_locks 与自身连接查询
- 打开锁等待日志并等待
- 对受阻查询运行 EXPLAIN