Stack Overflow 社区您好,
我正在开发一个带有单个 PostgreSQL 数据库的整体应用程序,并且我有需要事务性但涉及耗时操作的方法。考虑以下示例:
void sample(Item item) {
Item2 item2 = saveData1();
createPDF(item2.id);
savePdf();
saveData2()
}
我犹豫是否要使整个方法@Transactional,因为它可能会长时间阻塞数据库。虽然我知道在出现问题时处理回滚的传奇设计模式,但对于这个特定的用例来说,它似乎有点太复杂了。
我正在寻求有关替代设计模式或解决方案的建议,这些模式或解决方案将使我能够保持事务完整性,而不会长时间阻塞数据库。是否有任何既定的最佳实践或设计模式来处理单体应用程序中的此类场景?
感谢您的见解!
我尝试过的:
我尝试在我的整体应用程序中执行示例方法。
我预期会发生什么:
我预计该方法能够成功执行,在合理的时间范围内完成事务操作。
实际结果:
但是,我观察到,将整个方法设置为@Transactional 会导致数据库长时间阻塞,从而影响性能。我现在正在探索替代设计模式或解决方案来解决这个问题。
如果事务回滚会发生什么?例如。代码创建并保存了 PDF,回滚时 PDF 会被删除吗?
带着这个问题,我试图探讨是否真的需要交易?系统可能会承受一些不一致的情况吗?也许系统可能会承受一些暂时的不一致,并有一个单独的进程来稍后清理它?
另一种方法是将繁重的计算与实际的事务更新分离。例如,有没有办法在交易之外创建 PDF?然后运行所有保存/更新操作?显然,您需要数据库中的 ID 来生成 PDF,是否有选项可以优化它?我们可以为此使用外部 ID 生成器吗?
另一个角度:数据库为什么被锁?是整个数据库被锁定还是只是某些行/记录/对象被锁定?有外部锁服务的空间吗?
TL;DR - 我要么探索 Saga 方法,要么将所有昂贵的操作从事务代码中移出;第二种方法将是我首选的探索向量,因为即使在 Saga 背景下这也是有意义的。