【发布时间】:2018-11-30 09:13:53
【问题描述】:
我有两个功能都需要交易。一个正在呼叫另一个。我有可以使用 SAVEPOINT 将此类事务嵌套到单个事务中的代码。
如果它们具有相同的事务隔离级别,则没有问题。现在,如果他们不这样做,我还有办法“正确”合并交易吗?
如果我在两者中最严格的隔离级别下运行这两个事务,除了性能下降之外还有什么风险?
【问题讨论】:
标签: sql postgresql transactions isolation-level
我有两个功能都需要交易。一个正在呼叫另一个。我有可以使用 SAVEPOINT 将此类事务嵌套到单个事务中的代码。
如果它们具有相同的事务隔离级别,则没有问题。现在,如果他们不这样做,我还有办法“正确”合并交易吗?
如果我在两者中最严格的隔离级别下运行这两个事务,除了性能下降之外还有什么风险?
【问题讨论】:
标签: sql postgresql transactions isolation-level
在这种情况下,是的,通常您可以将事务组合成更严格的隔离级别。
风险在于更高的隔离级别会捕获更多的序列化错误(即 REPEATABLE READ 中的 ERROR: could not serialize access due to concurrent update 和 SERIALIZABLE 中的 ERROR: could not serialize access due to read/write dependencies among transactions)。处理这些序列化失败的典型方法是重试事务,但您应该验证这在您的应用程序上下文中是否有意义。
另一个可能发生的错误是死锁。 Postgres 应该检测到这些并打破死锁(在此之后失败的事务应该重试),但是如果可以的话,你应该总是尝试编写你的应用程序,这样死锁就不会首先存在。一般来说,避免死锁的主要技术是确保所有获取任何锁(隐式或显式锁)的应用程序以一致的顺序获取这些锁。
如果您的应用程序需要向另一个外部服务发出请求,您可能需要特别小心,因为您可能需要验证重试是否会导致您发出不需要的重复请求,尤其是在这些外部请求不是幂等的情况下.
【讨论】: