我应该避免大交易并从交易中排除只读查询吗

Should I avoid big transaction and exclude read-only queries from transaction

我看到文章说我们应该尽量限制交易的范围,例如而不是这样做:

@Transactional
public void save(User user) {
      queryData();
      addData();
      updateData();
}

我们应该使用 Spring 的 TransactionTemplatequeryData 从交易中排除(或者只是将其移出交易方法):

@Autowired
private TransactionTemplate transactionTemplate;
   
public void save(final User user) {
      queryData();

      transactionTemplate.execute((status) => {
         addData();
         updateData();
         return Boolean.TRUE;
      })
}

但我的理解是,自JDBC will always need a transaction for all operations以来,如果我使用第二种方式,将有2笔交易打开和关闭,1笔用于queryData(由JDBC打开),另一个用于我们的 class 打开的 transactionTemplate.execute 内的代码。如果是这样,现在您将 1 笔交易拆分为 2 笔交易,这不是浪费资源吗?

如果一个事务开始,它将用完一个数据库连接。所以我们一般希望事务尽快完成,尽可能延迟启动,直到真正需要访问DB,这样连接池才有更多的时间提供更多的可用连接给其他请求使用。

因此,如果您的功能中的部分工作流需要花费一些时间来完成他们的工作,并且该工作不需要访问数据库,那么最好限制事务的范围以排除这种情况部分代码。

但是在你的示例中,由于两个事务都是串行执行的并且都需要访问 DB ,所以我看不出有什么可以将它们分成两个不同的事务。

此外,就 Hibernate 而言,在同一事务中加载和更新实体是非常正常的,这样如果您更新的实体是从另一个已经关闭的实体加载的,则无需处理分离的实体交易。如果您不熟悉 Hibernate,则处理分离实体 is not easy