在 PostgreSQL 中提交事务会失​​败吗?

Can committing an transaction in PostgreSQL fail?

如果我在一个事务中成功执行了一些SQL,会不会发生提交失败的情况?可能的原因是什么?它会因执行的查询而失败,还是仅由于某些数据库方面的问题?

出现这个问题是因为我需要判断在测试中提交事务是否有意义,或者是否 "safe enough" 在每个测试用例之后回滚。

If I execute some SQL inside a transaction successfully, can it happens that the commit will fail?

是的。

And what are possible causes?

  • DEFERRABLE 约束 SET CONSTRAINTS DEFERRED 或在单语句自动提交事务中。 (除非您使用 DEFERRABLE 约束,否则不会发生)
  • SERIALIZABLE 提交时检测到序列化失败的事务。 (除非您使用 SERIALIZABLE 笔交易,否则不会发生)
  • 数据库崩溃或关闭的异步提交。 (如果 synchronous_commit = on,默认情况下不会发生)
  • 磁盘I/O错误、文件系统错误等
  • 内存不足错误
  • 网络错误导致会话在您发送 commit 之后但在您获得成功确认之前断开。在这种情况下,您不确定它是否已提交。
  • ...可能更多

Can it fail related to the executed queries, or just due to some DB side issues?

要么。例如,序列化失败肯定与查询 运行.

有关

如果您使用 READ COMMITTED 没有延迟约束的隔离,那么提交很可能会因为底层系统错误而失败。

The question comes up because I need to judge if it makes sense to commit transactions inside tests or if it is "safe enough" to just rollback after each test case.

任何合理的测试套件都必须涵盖多个并发事务交互、以不同顺序提交等。

如果您测试的只是单个独立事务,那么您并不是在测试真实系统。

所以这个问题在 IMO 没有实际意义,因为无论如何都必须提交一套像样的测试。