javax.transaction.Transactional vs org.springframework.transaction.annotation.Transactional

sta*_*mis 120 java spring hibernate transactions jta

我不明白注释javax.transaction.Transactional和实际区别是什么org.springframework.transaction.annotation.Transactional

org.springframework.transaction.annotation.Transactional延伸javax.transaction.Transactional还是他们有完全不同的含义?应该何时使用它们?@Transactinal服务层中的Spring 和DAO中的javax

谢谢回答.

JB *_*zet 101

几年前,Spring已经定义了自己的Transactional注释来使Spring bean方法成为事务性的.

Java EE 7最终完成了同样的事情,现在除了EJB方法之外,还允许CDI bean方法是事务性的.因此,从Java EE 7开始,它还定义了自己的Transactional注释(显然它不能重用Spring).

在Java EE 7应用程序中,您将使用Java EE注释.

在Spring应用程序中,您将使用Spring注释.

它们的用法是相同的:通知容器(Java EE或Spring)方法是事务性的.

  • 更重要的是:为了统治宇宙,Spring还为`javax.transaction.Transactional`添加了隐式支持,因此现在可以在Spring应用程序中使用它而无需任何其他操作.IMO,**从设计的角度来看这是一个非常糟糕的决定**,因为根据我的经验,许多开发人员无意中将这两者混淆在他们的代码中,这导致了之后的问题. (22认同)
  • 此外,`org.springframework.transaction.annotation.Transactional`提供了比`javax.transaction.Transactional更多的选项(比如`readOnly`,`timeout`). (9认同)
  • @yura,你观察到什么问题? (2认同)
  • @LeeCheeKiam 请看下面的两个答案 (2认同)

Jid*_*hem 46

另一个区别是Spring如何处理@Transactional注释

  • org.springframework.transaction.annotation.Transactional始终被考虑在内
  • 仅当存在EJB3事务时才考虑javax.transaction.Transactional.EJB3事务的存在是通过检查类javax.ejb.TransactionAttribute路径中是否可用类(从版本2.5.3到3.2.5)来完成的.因此,如果仅javax.transaction.Transactional在类路径中而不是,则最终可能不会考虑您的注释javax.ejb.TransactionAttribute.如果您正在使用Hibernate,情况就是这样:hibernate-core(4.3.7.Final)依赖于jboss-transaction-api_1.2_spec(1.0.0.Final),但它没有提供javax.ejb.TransactionAttribute.

  • 我认为这不再是Spring 4.2.0的问题了:[javax.transaction.Transactional annotation也支持作为Spring自己的注释的替代品](http://docs.spring.io/spring/docs/ 4.2.0.RELEASE /弹簧框架参考/ HTML/transaction.html#事务声明的注解) (6认同)

Lyj*_*son 30

请小心,(这个问题发生在tomcat),

如果您的应用程序是SPRING Web应用程序,并且您正在使用Spring的事务处理机制 @org.springframework.transaction.annotation.Transactional,那么请不要将其与javax.transaction.Transactional混合使用.

这是始终使用, @org.springframework.transaction.annotation.Transactional在弹簧应用程序中始终如一.

否则我们可能会遇到此错误,

org.springframework.orm.jpa.JpaSystemException: commit failed; nested exception is org.hibernate.TransactionException: commit failed

........

Caused by: java.sql.SQLException: Protocol violation: [0]
Run Code Online (Sandbox Code Playgroud)

  • 注意:这个答案是我的答案的特例 (2认同)

Vla*_*cea 22

声明式事务范围

Spring 和 JPA@Transaction注释都允许您定义给定应用程序事务的范围。

所以,如果一个服务方法被注解了@Transactional,它将在事务上下文中运行。如果服务方法使用多个 DAO 或 Repositories,则所有读写操作都将在同一个数据库事务中执行。

春天 @Transactional

org.springframework.transaction.annotation.Transactional注解自 Spring 框架的 1.2 版本(大约 2005 年)开始可用,它允许您设置以下事务属性:

  • isolation:底层数据库隔离级别
  • noRollbackForand noRollbackForClassNameException可以在不触发事务回滚的情况下触发的 Java类列表
  • rollbackForrollbackForClassNameException抛出时触发事务回滚的Java类列表
  • propagation: PropagationEnum给出的交易传播类型。例如,如果事务上下文可以被继承(例如,REQUIRED)或应该创建一个新的事务上下文(例如,REQUIRES_NEW),或者如果不存在事务上下文(例如,MANDATORY)或者是否应该抛出异常,则应该抛出异常如果找到当前事务上下文(例如,NOT_SUPPORTED)。
  • readOnly: 当前事务是否应该只读取数据而不应用任何更改。
  • timeout:在抛出超时异常之前,应允许事务上下文运行多少秒。
  • valuetransactionManagerTransactionManager绑定事务上下文时要使用的 Spring bean的名称。

Java EE @Transactional

javax.transaction.Transactional注解是由 Java EE 7 规范(大约 2013 年)添加的。因此,Java EE 注释的添加比 Spring 对应的注释晚了 8 年。

Java EE@Transactional只定义了 3 个属性:

  • dontRollbackOnException可以在不触发事务回滚的情况下触发的 Java类列表
  • rollbackOnException抛出时触发事务回滚的Java类列表
  • value:传播策略,由TxType枚举给出。例如,如果事务上下文可以被继承(例如,REQUIRED)或应该创建一个新的事务上下文(例如,REQUIRES_NEW),或者如果不存在事务上下文(例如,MANDATORY)或者是否应该抛出异常,则应该抛出异常如果找到当前事务上下文(例如,NOT_SUPPORTED)。

选择哪一个?

如果您使用的是 Spring 或 Spring Boot,则使用 Spring@Transactional批注,因为它允许您配置比 Java EE@Transactional批注更多的属性。

如果您单独使用 Java EE,并且将应用程序部署在 Java EE 应用服务器上,则使用 Java EE@Transactional注释。

  • 最有可能的是,不是。当从不同层(例如网络或调度程序)调用服务时,事务边界应该开始。 (2认同)
  • 私有方法不算数。只有服务间方法才计入[传播规则](https://docs.oracle.com/javaee/7/api/javax/transaction/Transactional.TxType.html)。 (2认同)