简体   繁体   English

春季:处理带有事务性数据库方法的长期Web服务调用的最佳方法?

[英]Spring: Best way to handle long-running web-service calls with transactional DB methods?

We have a service method which does approximately the following: 我们有一种服务方法,可以大致执行以下操作:

@Transactional
public void serviceMethod(...){
   for(Item i : bunchOfItems){
      webServices.webServiceCall(...);
      dao.daoUpdateMethod(...);
   }
}

The problem is that as soon as an update occurs the DB is holding a lock on the table for the duration of the Transaction (webservice calls average 5 sec each). 问题在于,一旦发生更新 ,数据库就会在事务持续时间内将保持在锁上 (每个Web服务平均调用5秒)。 Any exception in a webservice call or DAO call should, of course, cause a full rollback. 当然,Web服务调用或DAO调用中的任何异常都应引起完全回滚。

What's the best approach to this situation? 解决这种情况的最佳方法是什么?

If the web service call doesn't depend on what you might have updated in a previous iteration, you could make all your web service calls in a first pass and collect the results in memory, and then start a transaction for all your updates. 如果Web服务调用不取决于您在上一次迭代中可能进行的更新,则可以在第一次通过时进行所有Web服务调用,并将结果收集在内存中,然后为所有更新启动事务。 This would make your transaction much shorter and, since I assume the web service call isn't transactional anyway, it wouldn't affect the coherence of your data. 这将使您的事务变得更短,并且由于我假设Web服务调用无论如何都不是事务性的,因此不会影响您数据的一致性。

Because I assume the webservice call is not transactional in any way, you can do all webservice calls before you start the transaction to store something. 因为我假设Web服务调用绝不是事务性的,所以可以在开始事务存储任何东西之前进行所有Web服务调用。

You can do the whole stuff in different ways: 您可以用不同的方式完成全部工作:

  • sequential - 2 loops, one transaction and a bit memory: loop trough all webservice invocation store the results in an array, open the transaction and then loop trough all results and store them 顺序-2个循环,一个事务和一点内存:通过所有Web服务调用的循环将结果存储在数组中,打开事务,然后循环通过所有结果并将其存储
  • sequential - one loop, and n transaction: in the loop, first call the web service for one item, then start a new transaction and store it (loop end) 顺序-一个循环,和n个事务:在循环中,首先为一个项目调用Web服务,然后开始一个新的事务并存储它(循环结束)
  • in parallel - do the web service invokation in parallel - you can combine it with the two ways mentioned above like JB Nizet suggested his answer 并行-并行进行Web服务调用-您可以将其与上述两种方式结合使用, 例如JB Nizet建议他的回答

By employing MVCC mode in the database I can avoid locking on updates altogether. 通过在数据库中使用MVCC模式,我可以避免完全锁定更新。 After doing this I can perform the same test without any lock contention. 完成此操作后,我可以执行相同的测试而没有任何锁争用。

MVCC mode allows reads to occur while an uncommitted update is still in progress. MVCC模式允许在未提交的更新仍在进行时进行读取。

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

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