简体   繁体   English

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

[英]How to handle transactions in Async calls

Due to the slowness of the application, we made some of our long running queries asynchronous.由于应用程序运行缓慢,我们将一些长时间运行的查询设为异步。 Problem is these are part of a single transaction but in case if these queries/routines fail I need to roll back everything.问题是这些是单个事务的一部分,但如果这些查询/例程失败,我需要回滚所有内容。 How to achieve this?如何做到这一点? This application is legacy application using JDBC oracle and java 8. Also like to know if there is any support for this in Springboot, jpa application.此应用程序是使用 JDBC oracle 和 java 8 的遗留应用程序。还想知道 Springboot jpa 应用程序是否对此有任何支持。

Thanks in advance.提前致谢。

  • Don't try to interact with the same DB connection from multiple threads at once.不要尝试同时与来自多个线程的同一个数据库连接进行交互。 JDBC's connection system isn't specced to let you do this. JDBC 的连接系统并未指定让您这样做。
  • A transaction belongs to a single connection.事务属于单个连接。 You can't smear it out over multiples.你不能把它涂抹在倍数上。
  • The obvious way to ensure that 'it is all rolled back' is to have a single long-lived transaction (but see later).确保“全部回滚”的明显方法是拥有一个长期存在的事务(但请参阅下文)。

Combine these 3 facets and you end up with: Do all work in the async block.结合这 3 个方面,您最终会得到: 在异步块中完成所有工作。 At least, all work that either needs to all happen, or none of it happens (ie the one transaction).至少,所有需要全部发生或都不发生的工作(即一次交易)。

Any other basic approach wouldn't work or wouldn't be useful;任何其他基本方法都不起作用或没有用; there's no point freezing the main thread to wait for the async task (just do the async task on the spot; moving code to another thread doesn't magically make it go any faster. On the contrary, in fact).没有必要冻结主线程来等待异步任务(只需当场执行异步任务;将代码移动到另一个线程并不能神奇地使其 go 更快。相反,事实上)。

However, transactions that aren't just long lived, but make a ton of changes to a DB is its own problem, but we now we're getting into the performance characteristics of your specific batch of queries and your particular DB engine, version, indices, and data.然而,事务不仅长期存在,而且对数据库进行大量更改是它自己的问题,但我们现在正在研究特定查询批次和特定数据库引擎、版本的性能特征,指数, 数据. Kinda hard to answer with specifics, what with all those unknowns.有点难以回答具体问题,因为所有这些未知数。

There are ways to design your DB to deal with this (mostly involving a table representing a calculation, and having a row indicate whether the calculation is complete or not. As long as you aren't done, dont set it to 'completed', and all your queries should ignore non-complete results. Upon bootup, delete (and with it, let that cascade) any non-complete results: Those must be half-baked work done right before your server crashed, and now you've restarted it).有一些方法可以设计你的数据库来处理这个问题(主要涉及一个表示计算的表,并且有一行指示计算是否完成。只要你没有完成,就不要将其设置为“完成”,并且您的所有查询都应忽略不完整的结果。启动时,删除(并随之级联)任何不完整的结果:这些必须是在服务器崩溃之前完成的半生不熟的工作,现在您已经重新启动它)。 It's probably not the right answer here, just making sure you're aware that such options also exist.这可能不是正确的答案,只是确保您知道这样的选项也存在。

As a general rule of thumb, countering a problem of "Our code has been observed to run too slowly" with "lets make it all async" doesn't work.作为一般经验法则,用“让它全部异步”来解决“我们的代码运行速度太慢”的问题是行不通的。 async makes code harder to read, way harder to debug, and doesn't make stuff go faster. async 使代码更难阅读,更难调试,并且不会使 go 更快。 All you can really do with async is soothe the user by playing them some elevator music or slightly more pragmatic: A progress bar or whatnot, whilst they wait.使用 async 你真正能做的就是通过播放一些电梯音乐或更实用的音乐来安抚用户:在他们等待时播放进度条或诸如此类的东西。 And that's actually generally easier by spawning off the bits that tell the user what's happening into a separate thread, instead of asyncing the work itself.实际上,通过将告诉用户正在发生什么的位生成到一个单独的线程中,而不是异步工作本身,这实际上通常更容易。 That, and make your algorithm better and/or fix your DB index definitions.那,并使您的算法更好和/或修复您的数据库索引定义。 You can search the web for that too;你也可以搜索web; run EXPLAIN variants of your queries to make the DB tell you whether it is using any table sweeps (that's where it goes through the entire dataset before it can answer a query. You want to avoid those).运行查询的 EXPLAIN 变体,使数据库告诉您它是否正在使用任何表扫描(这是它在回答查询之前遍历整个数据集的地方。您想避免这些)。

If you need help with either of those parts (show the user what is going on, instead of freezing the webpage or freezing the GUI / how to optimize a DB query), search the web for this information, there are tons of tutorials.如果您需要有关这些部分的帮助(向用户展示正在发生的事情,而不是冻结网页或冻结 GUI/如何优化数据库查询),请搜索 web 以获取此信息,那里有大量教程。 Make sure to include the frontend tech;确保包括前端技术; java can be used for swing apps, javafx, android, and there are at last count like a 100 web frameworks. java 可用于 swing 个应用程序,javafx,android,最后有 100 个 web 框架。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM