声明式事务与程序化事务

时间:2015-07-03 10:11:59

标签: java spring hibernate orm transactions

如果我们选择程序化交易,我们会写

Session session=sessiongFactory.openSession();
Transaction tx=session.buildTransaction();

对于会话,我们可以构建我们想要的任意数量的事务。

所以,我们有第一个会话对象,而不是我们获得的事务对象。

在声明式事务中,如果我们在服务级别声明@Transaction注释。 “当调用此服务方法时,交易将被打开”,所以这里没有任何关于会话的信息。 然后在道我们写

Session session=sessiongFactory.getCurrentSession();

这里我们先进行Transation then Session,

任何人都可以帮助我理解,Spring如何管理这个声明性交易。

4 个答案:

答案 0 :(得分:4)

根据文档方法 sessiongFactory.getCurrentSession()获取当前会话和"当前会话"表示由配置使用的 CurrentSessionContext impl控制。

文档还提供了向后兼容性的解释:如果未配置 CurrentSessionContext 但配置了 JTA TransactionManagerLookup ,则默认为 JTASessionContext impl。

如果JTA事务生效,

JTASessionContext 实现将根据需要生成Sessions。如果在调用 currentSession()时会话尚未与当前JTA事务关联,则将打开一个新会话,它将与该JTA事务关联。

答案 1 :(得分:2)

使用Spring declarative transaction管理,您可以apply @Transactional同时使用&{班级。 它是通过AOP proxies启用的。 AOP与事务元数据的组合产生一个AOP代理,该代理使用TransactionInterceptor和适当的PlatformTransactionManager实现来驱动围绕方法调用的事务。

从概念上讲,在事务代理上调用方法看起来像这样......

enter image description here

使用代理时,您应该仅将@Transactional注释应用于具有公共可见性的方法。如果使用@Transactional注释注释protected,private或package-visible方法,则不会引发错误,但带注释的方法不会显示已配置的事务设置。

所有交易都与会话相关联。事务在服务层上启动,但它们必须与要提交的会话相关联。第一个事务完成,然后会话关闭。会话还可以跨越多个事务。如果你正在使用hibernate,spring使用hibernate托管事务管理器,负责将事务与hibernate会话相关联。

答案 2 :(得分:1)

Spring transaction management抽象事务处理并将事务划分逻辑(例如@Transactional)与实际事务管理器(例如RESOURCE_LOCAL,JTA)分离。

程序化事务的问题在于您将应用程序代码绑定到事务管理逻辑。另一方面,Spring允许您只使用一些配置从JpaTransactionManager切换到JtaTransactionManager(无需更改应用程序代码)。

Spring只创建一个事务上下文,内部TransactionInterceptor使用该事务上下文来执行实际的事务管理挂钩。

  1. 对于RESOURCE_LOCAL,事务通过JDBC Connection commit()和rollback()方法处理。

  2. 对于JTA,事务是通过JTA UserTransaction commit()和rollback()方法处理的。

答案 3 :(得分:0)

docs中解释了所有内容。您可能还想查看Spring integration with ORM

基本上,Spring创建一个代理,它拦截事务方法调用并在委托调用target方法之前启动事务,并在目标方法返回时结束事务。