[ PROMPT_NODE_23526 ]
lock-short-transactions
[ SKILL_DOCUMENTATION ]
## 保持事务简短以减少锁竞争
长时间运行的事务会持有锁,从而阻塞其他查询。请尽量缩短事务时间。
**错误示例(包含外部调用的长事务):**
sql
begin;
select * from orders where id = 1 for update; -- 获取锁
-- 应用程序向支付 API 发起 HTTP 调用(2-5 秒)
-- 该行的其他查询被阻塞!
update orders set status = 'paid' where id = 1;
commit; -- 锁在整个持续时间内被持有
**正确示例(最小化事务范围):**
sql
-- 在事务外验证数据并调用 API
-- 应用程序: response = await paymentAPI.charge(...)
-- 仅在实际更新时持有锁
begin;
update orders
set status = 'paid', payment_id = $1
where id = $2 and status = 'pending'
returning *;
commit; -- 锁仅持有几毫秒
使用 `statement_timeout` 防止失控事务:
sql
-- 中止运行超过 30 秒的查询
set statement_timeout = '30s';
-- 或针对会话设置
set local statement_timeout = '5s';
参考:[事务管理 (Transaction Management)](https://www.postgresql.org/docs/current/tutorial-transactions.html)