【问题标题】:autocommit and @Transactional and Cascading with spring, jpa and hibernate使用 spring、jpa 和 hibernate 自动提交和 @Transactional 和级联
【发布时间】:2026-01-25 10:00:01
【问题描述】:

我想要完成的是:

  1. 已启用自动提交,因此默认情况下所有查询都会提交
  2. 如果方法上有@Transactional,它会覆盖自动提交并将所有查询包含在单个事务中,从而覆盖自动提交
  3. 如果有一个@Transactional方法调用其他@Transactional注解的方法,最外层的注解应该覆盖内部的注解并创建一个更大的事务,因此注解也会相互覆盖

我目前仍在学习 spring-orm,找不到有关此的文档,并且还没有测试项目。

所以我的问题是:

  • 春季交易的默认行为是什么?
  • 如果默认值与我的要求不同,有没有办法配置我想要的行为?
  • 还是有完全不同的交易最佳实践?

--编辑--

我有以下测试设置:

@javax.persistence.Entity
public class Entity {
  @Id
  @GeneratedValue
  private Integer id;
  private String name;
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
}

@Repository
public class Dao {
  @PersistenceContext
  private EntityManager em;
  public void insert(Entity ent) {
    em.persist(ent);
  }
  @SuppressWarnings("unchecked")
  public List<Entity> selectAll() {
    List<Entity> ents = em.createQuery("select e from " + Entity.class.getName() + " e").getResultList();
    return ents;
  }
}

如果我有这样的设置,即使在休眠中启用了自动提交,插入方法也不会执行任何操作。我必须将@Transactional 添加到插入或调用插入的方法中才能工作...

有没有办法让@Transactional 完全可选?

【问题讨论】:

    标签: java hibernate spring orm jpa


    【解决方案1】:
    • 在休眠状态下,如果没有活动事务,您将无法进行查询
    • @Transactional 有一个propagation 属性,用于标识调用新方法时的事务行为。默认是REQUIRED,这是你想要的。 Here 您可以找到该概念的图形演示。
    • 如果您使用 aop 设置事务方法,则可以省略使用 @Transactional,如下所示:

      <aop:config>
          <aop:pointcut id="serviceMethods"
              expression="execution(* com.company.product.service..*.*(..))" />
          <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
      </aop:config>
      
      <tx:advice id="txAdvice" transaction-manager="transactionManager">
          <tx:attributes>
              <tx:method name="*" propagation="REQUIRED" />
          </tx:attributes>
      </tx:advice>
      

      这使得service 包中的所有公共方法都是事务性的。

    另外,请随意阅读有关 Spring 事务的整章。

    【讨论】:

    • 嗯,好吧,这行得通,似乎我对使用自动提交的想法无论如何都是个坏主意。我认为对我来说,正确地注释服务会是更好的做法。任何数据库操作的自动提交都太容易导致损坏状态。我应该使用白名单(隐喻),而不是采用黑名单方法。我将尝试创建一个建议,将@Transactional 添加到所有使用@Service 注释的bean。虽然首先阅读了关于 spring-aop 的信息。 :) 谢谢
    • 事务性的建议毕竟是个坏主意:--ibm.com/developerworks/java/library/…--*.com/questions/1882959/…--我的解决方案是只注释执行写入操作的方法,其余的不注释。添加propagation=SUPPORTS 和readonly=true 可能会提高hibernate 的性能,但目前这对我来说太费力了,无法投入到aspectj CTW 方面。
    • 我刚刚遇到过这样的问题,发现您对 readOnly=true 和propagation=SUPPORTS 的引用。只是一句警告:ibm.com/developerworks/java/library/j-ts1/index.html#N101B1 那样不行。
    最近更新 更多