在使用postgresql时,当在事务块中SQL执行出错后,继续执行任何SQL都会报错如下,必须rollback;
ERROR: current transaction is aborted, commands ignored until end of transaction block
postgresql 事务块中不允许出错,任何一个SQL出错后,事务为变为aborted,必须rollback掉重来。
这与其它库数据库不同,如ORACLE,只是当前SQL失败,事务还可以继续。
postgresql jdbc驱动中,可通在连接数据库时可以设置如下参数,会在每条语句前自动加一个隐式的SAVEPOINT,报错后自动回滚事务到SAVEPOINT,来保证整个事务不会abort,但会降低性能。
String url = "jdbc:postgresql://localhost/test?autosave=always&cleanupSavePoints=ture";
-
autosave = String
Specifies what the driver should do if a query fails. In autosave=always mode, JDBC driver sets a savepoint before each query, and rolls back to that savepoint in case of failure. In autosave=never mode (default), no savepoint dance is made ever. In autosave=conservative mode, savepoint is set for each query, however the rollback is done only for rare cases like ‘cached statement cannot change return type’ or ‘statement XXX is not valid’ so JDBC driver rollsback and retries
The default is never -
cleanupSavepoints = boolean
Determines if the SAVEPOINT created in autosave mode is released prior to the statement. This is done to avoid running out of shared buffers on the server in the case where 1000’s of queries are performed.
The default is ‘false’
psql客户端可以做如下设置达到该目的
\set ON_ERROR_ROLLBACK on
-
ON_ERROR_ROLLBACK
当被设置为on时,如果事务块中的一个语句产生一个错误,该错误会被忽略并且该事务会继续。当被设置为interactive时,只在交互式会话中忽略这类错误,而读取脚本文件时则不会忽略错误。当被重置或者设置为off(默认值)时,事务块中产生错误的一个语句会中止整个事务。错误回滚模式的工作原理是在事务块的每个命令之前都为你发出一个隐式的SAVEPOINT,然后在该命令失败时回滚到该保存点。 -
ON_ERROR_STOP
默认情况下,出现一个错误后命令处理会继续下去。当这个变量被设置为on后,出现错误后命令处理会立即停止。在交互模式下,psql将会返回到命令提示符;否则,psql将会退出并且返回错误代码 3 来把这种情况与致命错误区分开来,致命错误会被报告为错误代码 1。在两种情况下,任何当前正在运行的脚本(顶层脚本以及任何它已经调用的其他脚本)将被立即中止。如果顶层命名字符串包含多个 SQL 命令,将在当前命令处停止处理。