如何处理异步调用中的事务

How to handle transactions in Async calls

由于应用程序运行缓慢,我们将一些长 运行 查询设为异步。问题是这些是单个事务的一部分,但如果这些 queries/routines 失败,我需要回滚所有内容。如何做到这一点?此应用程序是使用 JDBC oracle 和 java 8 的遗留应用程序。还想知道 Springboot、jpa 应用程序是否对此有任何支持。

提前致谢。

  • 不要尝试同时从多个线程与同一个数据库连接进行交互。 JDBC 的连接系统并未指定让您执行此操作。
  • 一个事务属于一个连接。你不能把它涂抹在倍数上。
  • 确保 'it is all rolled back' 的明显方法是拥有一个长期存在的事务(但稍后会看到)。

结合这 3 个方面,您最终会得到:在异步块中完成所有工作。至少,所有工作 要么全部发生,要么 none 发生(即一次交易)。

任何其他基本方法都不起作用或没有用;没有必要冻结主线程来等待异步任务(只需当场执行异步任务;将代码移动到另一个线程并不会神奇地使其运行得更快。相反,事实上)。

然而,事务不仅存在时间长,而且对数据库进行大量更改是其自身的问题,但我们现在正在研究您的特定查询批次的性能特征和您的特定数据库引擎、版本、索引和数据。有点难以回答具体问题,所有这些未知数。

有一些方法可以设计你的数据库来处理这个问题(主要涉及一个 table 代表一个计算,并且有一行指示计算是否完成。只要你没有完成,不要将其设置为 'completed',并且您的所有查询都应忽略不完整的结果。启动时,删除(并与之一起级联)任何不完整的结果:这些必须是半生不熟的工作在你的服务器崩溃之前,现在你已经重新启动了它)。这可能不是正确的答案,只是确保您知道这样的选项也存在。

作为一般经验法则,用“让它全部异步”来解决“我们的代码已被观察到 运行 太慢”的问题是行不通的。 async 使代码更难阅读,更难调试,并且不会让事情变得更快。使用 async 你真正能做的就是通过播放一些电梯音乐或更实用的音乐来安抚用户:在他们等待时播放进度条或诸如此类的东西。实际上,通过将告诉用户正在发生什么的位生成到一个单独的线程中,而不是异步工作本身,这实际上通常更容易。那,并使您的算法更好 and/or 修复您的数据库索引定义。您也可以在网上搜索它; 运行 EXPLAIN 查询的变体,使数据库告诉您它是否正在使用任何 table 扫描(这是它在回答查询之前遍历整个数据集的地方。您想避免这些)。

如果您需要这些部分的帮助(向用户展示正在发生的事情,而不是冻结网页或冻结 GUI/如何优化数据库查询),请在网上搜索此信息,有大量教程。确保包括前端技术; java 可以用于 swing 应用程序,javafx,android,最后有 100 个 Web 框架。