【问题标题】:Spring: Best way to handle long-running web-service calls with transactional DB methods?Spring:使用事务性 DB 方法处理长时间运行的 Web 服务调用的最佳方式?
【发布时间】:2011-08-10 03:05:53
【问题描述】:

我们有一个服务方法,它大致执行以下操作:

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

问题在于,一旦发生更新,数据库就会在事务期间持有对表的锁定(网络服务调用平均每次 5 秒)。当然,Web 服务调用或 DAO 调用中的任何异常都会导致完全回滚。

解决这种情况的最佳方法是什么?

【问题讨论】:

  • 为什么更新会锁定整个表?在任何体面的 DBMS 中,它只会锁定已更新的行。
  • 这个问题和Spring无关,是一般的问题。

标签: java database spring transactions


【解决方案1】:

如果 Web 服务调用不依赖于您在上一次迭代中可能更新的内容,您可以在第一遍中进行所有 Web 服务调用并将结果收集到内存中,然后为您的所有更新。这将使您的事务更短,而且由于我假设 Web 服务调用无论如何都不是事务性的,因此不会影响数据的一致性。

【讨论】:

    【解决方案2】:

    因为我假设 web 服务调用在任何情况下都不是事务性的,所以您可以在开始事务之前执行所有 web 服务调用来存储一些东西。

    你可以用不同的方式做所有的事情:

    • 顺序 - 2 个循环,一个事务和一个位内存:循环遍历所有 Web 服务调用,将结果存储在一个数组中,打开事务,然后循环遍历所有结果并存储它们
    • sequential - 一个循环,n 个事务:在循环中,首先为一个项目调用 Web 服务,然后开始一个新事务并存储它(循环结束)
    • 并行 - 并行执行 Web 服务调用 - 您可以将其与上述两种方式结合使用 like JB Nizet suggested his answer

    【讨论】:

      【解决方案3】:

      通过在数据库中使用 MVCC 模式,我可以完全避免锁定更新。完成此操作后,我可以执行相同的测试而不会发生任何锁争用。

      MVCC 模式允许在未提交的更新仍在进行时进行读取。

      【讨论】:

        猜你喜欢
        • 2017-08-24
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-29
        • 1970-01-01
        相关资源
        最近更新 更多