【问题标题】:Validating that all JDBC calls happen within a transaction验证所有 JDBC 调用是否发生在事务中
【发布时间】:2009-08-05 23:05:25
【问题描述】:

如何验证所有 JDBC 访问是否发生在活动事务中,java.sql.Connection.getAutoCommit() 始终返回 false?

我使用 Spring 进行事务管理 (@Transactional) 并使用 Hibernate 进行数据访问。


更新:发生的情况是某些 Hibernate 访问是在没有使用 @Transactional 注释的服务方法的情况下执行的。这就是我想收到的通知。

更新 2:代码示例

可以调用如下代码:

public ServiceImpl implements Service {

     // missing @Transactional
     public List<String> getSomeIds() {
           return getDao().getSomeIds();
     }
}

【问题讨论】:

    标签: java hibernate spring


    【解决方案1】:

    在所有持久化方法上使用PROPAGATION_REQUIRED

    【讨论】:

    • 感谢您的回答。发生的情况是某些 Hibernate 访问是在没有使用 @Transactional 注释的服务方法的情况下执行的。这就是我想收到的通知。
    • 请举一个没有service方法的Hibernate访问示例。这一切都应该通过服务层发生。如果你愿意,你可以写一个切面来明确禁止服务层之外的 DAO 访问。
    • 为什么在事务外读取是个问题?我可能在这里无知,但我认为写操作是必须担心 ACID 的操作。如果这有那么大的问题,那么简单地添加注释会不会比跳过箍更好?我的建议是写方面或添加注释。
    【解决方案2】:

    我能想到的一种方法是实现并注册一个虚拟 JDBC 驱动程序,以充当您要监视的语句之间的拦截器,并记录何时 Connection#setAutoCommit() 和 Connection#commit()调用以了解事务的边界。

    【讨论】:

      【解决方案3】:

      您实际上不需要这样做,因为根据the @Transactional documentation,第 9.5.6.1 节:

      默认的@Transactional 设置是:

       The propagation setting is PROPAGATION_REQUIRED
       ....
      

      PROPAGATION_REQUIRED 表示:

      支持当前事务,如果不存在则创建一个新事务。

      编辑:您最好的选择可能是按照@duffymo 在他的评论中所说的:

      如果你愿意,你可以写一个切面来明确禁止服务层之外的 DAO 访问。

      【讨论】:

      • 感谢您的回答。发生的情况是某些 Hibernate 访问是在没有使用 @Transactional 注释的服务方法的情况下执行的。这就是我希望收到的通知。
      猜你喜欢
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2021-02-22
      • 2011-03-01
      • 1970-01-01
      相关资源
      最近更新 更多