如果我们选择程序化交易,我们会写
Session session=sessiongFactory.openSession();
Transaction tx=session.buildTransaction();
对于会话,我们可以构建我们想要的任意数量的事务。
所以,我们有第一个会话对象,而不是我们获得的事务对象。
在声明式事务中,如果我们在服务级别声明@Transaction
注释。
“当调用此服务方法时,交易将被打开”,所以这里没有任何关于会话的信息。
然后在道我们写
Session session=sessiongFactory.getCurrentSession();
这里我们先进行Transation then Session,
任何人都可以帮助我理解,Spring如何管理这个声明性交易。
答案 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实现来驱动围绕方法调用的事务。
从概念上讲,在事务代理上调用方法看起来像这样......
使用代理时,您应该仅将@Transactional注释应用于具有公共可见性的方法。如果使用@Transactional注释注释protected,private或package-visible方法,则不会引发错误,但带注释的方法不会显示已配置的事务设置。
所有交易都与会话相关联。事务在服务层上启动,但它们必须与要提交的会话相关联。第一个事务完成,然后会话关闭。会话还可以跨越多个事务。如果你正在使用hibernate,spring使用hibernate托管事务管理器,负责将事务与hibernate会话相关联。
答案 2 :(得分:1)
Spring transaction management抽象事务处理并将事务划分逻辑(例如@Transactional)与实际事务管理器(例如RESOURCE_LOCAL,JTA)分离。
程序化事务的问题在于您将应用程序代码绑定到事务管理逻辑。另一方面,Spring允许您只使用一些配置从JpaTransactionManager切换到JtaTransactionManager(无需更改应用程序代码)。
Spring只创建一个事务上下文,内部TransactionInterceptor
使用该事务上下文来执行实际的事务管理挂钩。
对于RESOURCE_LOCAL,事务通过JDBC Connection
commit()和rollback()方法处理。
对于JTA,事务是通过JTA UserTransaction
commit()和rollback()方法处理的。
答案 3 :(得分:0)
docs中解释了所有内容。您可能还想查看Spring integration with ORM。
基本上,Spring创建一个代理,它拦截事务方法调用并在委托调用target方法之前启动事务,并在目标方法返回时结束事务。