DBeaver连接PostgreSQL关闭自动提交后执行COMMIT仍有挂起事务问题
问题原因分析
- 首先是DBeaver的默认事务执行逻辑问题:DBeaver连接PostgreSQL时默认关闭自动提交,且默认开启「逐语句执行」模式,你运行的每一条独立SQL语句都会绑定一个单独的事务上下文,执行完成后不会自动提交,会作为挂起事务保留。
- 其次是语句执行的事务隔离问题:你写的
DO块和后续的COMMIT是两条独立的SQL语句,逐语句执行时:- 第一条执行
DO块时,DBeaver开启第一个事务运行删除逻辑,执行完成后事务保留,进入挂起状态 - 第二条执行
COMMIT时,DBeaver会新开第二个独立事务运行COMMIT命令,这条命令只会提交当前第二个空事务,对第一个执行DO块的事务没有任何作用,最终就会残留2个待提交的挂起事务
- 第一条执行
- 补充注意:PostgreSQL的匿名
DO块本身不支持内部写事务控制语句(COMMIT/ROLLBACK),如果需要在代码块内控制事务,需要将逻辑封装为存储过程(PROCEDURE)后通过CALL调用。
解决方案
你可以根据使用场景任选一种方案解决:
- 开启自动提交:打开对应PostgreSQL连接的「编辑连接」配置,找到「事务」选项卡,勾选自动提交事务,所有语句执行完成后会自动提交,不会产生挂起事务
- 整段执行脚本:选中所有需要运行的SQL内容,右键选择「执行SQL脚本」(而非「执行SQL语句」),整段脚本会在同一个事务上下文中运行,脚本末尾的
COMMIT会正常提交当前事务,不会残留挂起事务 - 直接使用IDE提交按钮:不需要在脚本中写
COMMIT,运行完DO块后直接点击IDE顶部的COMMIT按钮,会一次性提交当前连接下的所有挂起事务
内容的提问来源于stack exchange,提问作者S.Clementi
相关产品推荐
相关产品推荐

