我不明白注释 javax.transaction.Transactional
和 org.springframework.transaction.annotation.Transactional
之间的实际区别是什么?
org.springframework.transaction.annotation.Transactional
是 javax.transaction.Transactional
的扩展还是它们具有完全不同的含义?什么时候应该使用它们?服务层中的 Spring @Transactinal
和 DAO 中的 javax?
谢谢回答。
几年前,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 如何处理 @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 .
请小心,(这个问题发生在tomcat中),
如果您的应用程序是 SPRING Web 应用程序并且您正在使用 Spring 的事务处理机制 @org.springframework.transaction.annotation.Transactional
,那么不要将它与 javax.transaction.Transactional 混合使用。
即始终在 Spring 应用程序中始终使用 @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]
声明式事务范围
Spring 和 JPA @Transaction
注释都允许您定义给定应用程序事务的范围。
因此,如果使用 @Transactional
注释对服务方法进行注释,它将在事务上下文中运行。如果服务方法使用多个 DAO 或 Repositories,所有的读写操作都将在同一个数据库事务中执行。
春天@Transactional
org.springframework.transaction.annotation.Transactional
注释自 Spring 框架的 1.2 版本(大约 2005 年)以来一直可用,它允许您设置以下事务属性:
隔离:底层数据库隔离级别
noRollbackFor 和 noRollbackForClassName:可以在不触发事务回滚的情况下触发的 Java Exception 类的列表
rollbackFor 和 rollbackForClassName:抛出时触发事务回滚的 Java Exception 类列表
传播:Propagation Enum 给出的交易传播类型。例如,如果事务上下文可以被继承(例如,REQUIRED)或者应该创建一个新的事务上下文(例如,REQUIRES_NEW),或者如果不存在事务上下文(例如,MANDATORY)或者如果异常应该抛出异常如果找到当前事务上下文(例如,NOT_SUPPORTED),则应该抛出。
readOnly:当前事务是否应该只读取数据而不应用任何更改。
timeout:在抛出超时异常之前,应该允许事务上下文运行多少秒。
value 或 transactionManager:绑定事务上下文时要使用的 Spring TransactionManager bean 的名称。
Java EE @Transactional
javax.transaction.Transactional
注释是由 Java EE 7 规范(大约 2013 年)添加的。因此,Java EE 注释的添加比其 Spring 注释晚了 8 年。
Java EE @Transactional
只定义了 3 个属性:
dontRollbackOn:可以在不触发事务回滚的情况下触发的 Java Exception 类列表
rollbackOn:抛出时触发事务回滚的 Java Exception 类列表
value:传播策略,由 TxType Enum 给出。例如,如果事务上下文可以被继承(例如,REQUIRED)或者应该创建一个新的事务上下文(例如,REQUIRES_NEW),或者如果不存在事务上下文(例如,MANDATORY)或者如果异常应该抛出异常如果找到当前事务上下文(例如,NOT_SUPPORTED),则应该抛出。
选择哪一个?
如果您使用 Spring 或 Spring Boot,则使用 Spring @Transactional
注释,因为它允许您配置比 Java EE @Transactional
注释更多的属性。
如果您单独使用 Java EE,并且将应用程序部署在 Java EE 应用程序服务器上,则使用 Java EE @Transactional
注释。
private
方法?
不定期副业成功案例分享
javax.transaction.Transactional
的隐式支持,因此现在人们也可以在 Spring 应用程序中使用它,而无需任何额外的操作。 IMO,从设计的角度来看,这是一个非常糟糕的决定,因为根据我的经验,很多开发人员在他们的代码中不自觉地混淆了这两者,这会导致后来出现问题。org.springframework.transaction.annotation.Transactional
提供比javax.transaction.Transactional
更多的选项(如readOnly
、timeout
)