javax.transaction.Transactional与org.springframework.transaction.annotation.Transactional


152

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

org.springframework.transaction.annotation.Transactional扩展名javax.transaction.Transactional还是它们具有完全不同的含义?什么时候应该使用它们?@Transactinal在服务层中使用Spring ,在DAO 中使用javax

谢谢回答。

Answers:


125

几年前,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)方法是事务性的。


28
不仅如此:为了统治宇宙,Spring还添加了对隐式支持,javax.transaction.Transactional因此现在无需任何其他操作即可在Spring应用程序中使用它。IMO,从设计的角度来看这是一个非常糟糕的决定,因为根据我的经验,许多开发人员在代码中无意识地混淆了这两者,从而导致后来出现问题。
Yuriy Nakonechnyy

16
此外,org.springframework.transaction.annotation.Transactional提供的选项(如readOnlytimeout)要多于javax.transaction.Transactional
pierrefevrier 17-4-20

1
@yura,您发现了什么问题?
Lee Chee Kiam

1
@LeeCheeKiam请在下面看到两个答案
Yuriy Nakonechnyy

50

另一个区别是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


它并不总是采用的,例如,如果它采用私有方法,则不会采用。
播放

36

请小心,(此问题发生在tomcat中),

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

始终@org.springframework.transaction.annotation.Transactional在Spring应用程序中始终使用 。

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

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

........

Caused by: java.sql.SQLException: Protocol violation: [0]

1
注意:此答案是我答案的一个特例
Jidehem '17

3

声明式交易范围

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

因此,如果服务方法带有@Transactional注释,则它将在事务上下文中运行。如果服务方法使用多个DAO或存储库,则所有读取广告的写操作将在同一数据库事务中执行。

弹簧 @Transactional

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

  • isolation:基础数据库隔离级别
  • noRollbackFornoRollbackForClassNameException可以在不触发事务回滚的情况下触发的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:传播策略,由TxTypeEnum 给出。例如,如果可以继承事务上下文(例如REQUIRED),或者应该创建新的事务上下文(例如REQUIRES_NEW),或者如果不存在事务上下文(例如MANDATORY)或者应该引发异常,则应该引发异常如果找到当前交易环境(例如NOT_SUPPORTED)。

选择哪一个?

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

如果仅使用Java EE,并且将应用程序部署在Java EE应用程序服务器上,则使用Java EE``@ Transactional`批注。

有关使用Spring或Java EE @Transactional定义时隔离级别配置如何不同的更多详细信息,请参阅本文

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.