事务里一条语句失败了,整个事务还能继续吗?PostgreSQL 与 MySQL 为什么不一样?保存点怎么救?嵌套保存点的规则是什么?pgjdbc 的 autosave 值得开吗?这篇逐个触发。
1 重复主键的 INSERT 失败:PSQLException(23505) ERROR: duplicate key value violates unique constraint "t_pkey" 失败之后同一个事务里的下一条 INSERT:PSQLException(25P02) ERROR: current transaction is aborted, commands ignored until end of transaction block commit():没有报错 最终表里的 id:[] 2 在保存点之后重复主键失败:PSQLException(23505) ERROR: duplicate key value violates unique constraint "t_pkey" rollback(sp) 之后继续: 提交后表里的 id:[1, 2](第一次的 1 与恢复之后的 2 都保留)
3 三次插入、两个保存点之后,事务里的 id:[1, 2, 3] rollback(s2) 之后:[1, 2] 再 insert 4,然后 rollback(s1) 之后:[1] 再 rollback(s2):PSQLException(3B001) ERROR: savepoint "s2" does not exist 释放之后再 rollback(s1):PSQLException(25P02) ERROR: current transaction is aborted, commands ignored until end of transaction block 提交后表里的 id:[] 4 两个同名保存点 same:rollback(第二个)之后表里 [] 5 无名保存点 getSavepointId() = 0 无名保存点 getSavepointName():PSQLException(42809) Cannot retrieve the name of an unnamed savepoint. 命名保存点 getSavepointName() = x 命名保存点 getSavepointId():PSQLException(42809) Cannot retrieve the id of a named savepoint. 6 autocommit=true 时 setSavepoint:PSQLException(25P01) Cannot establish a savepoint in auto-commit mode. 7 commit 之后 rollback(旧保存点):PSQLException(25P01) ERROR: ROLLBACK TO SAVEPOINT can only be used in transaction blocks supportsSavepoints() = true
1 重复主键的 INSERT 失败:SQLIntegrityConstraintViolationException(23000) Duplicate entry '1' for key 't.PRIMARY' 失败之后同一个事务里的下一条 INSERT:成功 commit():没有报错 最终表里的 id:[1, 2] 2 在保存点之后重复主键失败:SQLIntegrityConstraintViolationException(23000) Duplicate entry '1' for key 't.PRIMARY' rollback(sp) 之后继续: 提交后表里的 id:[1, 2](第一次的 1 与恢复之后的 2 都保留)
3 三次插入、两个保存点之后,事务里的 id:[1, 2, 3] rollback(s2) 之后:[1, 2] 再 insert 4,然后 rollback(s1) 之后:[1] 再 rollback(s2):SQLSyntaxErrorException(42000) SAVEPOINT s2 does not exist releaseSavepoint(s1):成功 释放之后再 rollback(s1):SQLSyntaxErrorException(42000) SAVEPOINT s1 does not exist 提交后表里的 id:[1] 4 两个同名保存点 same:rollback(第二个)之后表里 [] 5 无名保存点 getSavepointId():SQLException(S1C00) Only named savepoints are supported. 无名保存点 getSavepointName() = e4e697bb_3f78_4cf1_82fa_e388322a4f26 命名保存点 getSavepointName() = x 命名保存点 getSavepointId():SQLException(S1C00) Only named savepoints are supported. 6 autocommit=true 时 setSavepoint:没有报错 7 commit 之后 rollback(旧保存点):SQLSyntaxErrorException(42000) SAVEPOINT old does not exist supportsSavepoints() = true
8 重复主键失败:PSQLException(23505) ERROR: duplicate key value violates unique constraint "t_pkey" 失败之后的下一条 INSERT:PSQLException(25P02) ERROR: current transaction is aborted, commands ignored until end of transaction block 最终表里的 id:[] 逐行插入 20000 行(一个事务):564.9 ms
8 重复主键失败:PSQLException(23505) ERROR: duplicate key value violates unique constraint "t_pkey" 失败之后的下一条 INSERT:成功(驱动在语句之前自动设了保存点) 最终表里的 id:[1, 2] 逐行插入 20000 行(一个事务):1111.3 ms
8 重复主键失败:PSQLException(23505) ERROR: duplicate key value violates unique constraint "t_pkey" 失败之后的下一条 INSERT:PSQLException(25P02) ERROR: current transaction is aborted, commands ignored until end of transaction block 最终表里的 id:[] 逐行插入 20000 行(一个事务):572.4 ms