Spring 事务管理问题
javaweb使用ssh框架,在service层上有@Transactional注解,即为了给service类里面的每个方法添加事务。我现在的疑惑是,Service层中的...
java web 使用ssh框架,在service层上有@Transactional注解,即为了给service类里面的每个方法添加事务。
我现在的疑惑是,Service层中的方法调用dao层中的方法,dao层中的方法调用hibernate的API,如通过获取session,执行对应的SQL等。
在service上添加事务是利用AOP思想,在service层方法执行前已打开session,开启了事务。那再执行service层方法时又再次打开session,这应该不是同一个session,这不就矛盾了了,事务怎么添加到service层方法上来的呢?
我不知道自己哪里理解的错了或者说错了,有哪位大神知道的,给小弟指点一二,不胜感激! 展开
我现在的疑惑是,Service层中的方法调用dao层中的方法,dao层中的方法调用hibernate的API,如通过获取session,执行对应的SQL等。
在service上添加事务是利用AOP思想,在service层方法执行前已打开session,开启了事务。那再执行service层方法时又再次打开session,这应该不是同一个session,这不就矛盾了了,事务怎么添加到service层方法上来的呢?
我不知道自己哪里理解的错了或者说错了,有哪位大神知道的,给小弟指点一二,不胜感激! 展开
展开全部
你说的在某个方法F上开启session,
1、如果F实现复杂功能,需要对多个不同数据库实例进行操作(跨库),从Java层框架的角度,这个session是一个逻辑上的事务,管理所有涉及的数据库实例的连接(一般使用连接池管理),成功则所有涉及的数据库实例的操作统一提交,失败则统一回滚。
2、如果F实现功能,只涉及对某个数据库进行操作,同上。
对于“在service层方法执行前已打开session,开启了事务。那再执行service层方法时又再次打开session,这应该不是同一个session,这不就矛盾了了,事务怎么添加到service层方法上来的呢?
”:不同Spring注解,功能是不一样的。如果你在F上加@Transactional(propagation = Propagation.REQUIRES_NEW),则前后肯定不处于同一个session上下文环境下。如果注解是@Transactional(propagation = Propagation.REQUIRED),则前后是处于同一个session上下文环境下。Spring会根据注解进行处理,表现为事务的传播特性,技术上通过AOP+代理+线程变量实现。对于开发者,一般只需要知道注解的用法以及注意事项即可。技术实现上,有兴趣可以下载源码查看或买本大牛的书籍学习。
1、如果F实现复杂功能,需要对多个不同数据库实例进行操作(跨库),从Java层框架的角度,这个session是一个逻辑上的事务,管理所有涉及的数据库实例的连接(一般使用连接池管理),成功则所有涉及的数据库实例的操作统一提交,失败则统一回滚。
2、如果F实现功能,只涉及对某个数据库进行操作,同上。
对于“在service层方法执行前已打开session,开启了事务。那再执行service层方法时又再次打开session,这应该不是同一个session,这不就矛盾了了,事务怎么添加到service层方法上来的呢?
”:不同Spring注解,功能是不一样的。如果你在F上加@Transactional(propagation = Propagation.REQUIRES_NEW),则前后肯定不处于同一个session上下文环境下。如果注解是@Transactional(propagation = Propagation.REQUIRED),则前后是处于同一个session上下文环境下。Spring会根据注解进行处理,表现为事务的传播特性,技术上通过AOP+代理+线程变量实现。对于开发者,一般只需要知道注解的用法以及注意事项即可。技术实现上,有兴趣可以下载源码查看或买本大牛的书籍学习。
展开全部
打开session不一定会开启事务。事务是通过session.beginTransaction()来开启
@Transactional注解要求事务传播级别的参数
required:将当前方法添加到当前事务,执行的是getCurrentSession而不是OpenSession
required-new:执行的是把当前session的事务提交,然后开启新的session
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
首先要明确 既然用了ssh框架 事务是由spring管理,而不是手动开启关闭。所以你要注意的不是怎么开,怎么关 而是得知道 什么时候开 什么时候关
<aop:config proxy-target-class="true">
<aop:pointcut id="interceptorPointCuts"
expression="execution(* com.haier..service..impl.*ServiceImpl.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />
</aop:config>
这里的配置文件 自动的对service层的方法进行了管理事务
而配置文件里的下面这个代码中的 REQUIRED属性对一个session里有2个以上事务时候,统一采用第一个事务
<tx:method name="find*" propagation="REQUIRED" read-only="true"/>
再有一般dao层采用currentSession的目的就是为了 不占用内存空间 尽量采用已有的session。所以一般都采用一个session
希望对你有所帮助~
<aop:config proxy-target-class="true">
<aop:pointcut id="interceptorPointCuts"
expression="execution(* com.haier..service..impl.*ServiceImpl.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />
</aop:config>
这里的配置文件 自动的对service层的方法进行了管理事务
而配置文件里的下面这个代码中的 REQUIRED属性对一个session里有2个以上事务时候,统一采用第一个事务
<tx:method name="find*" propagation="REQUIRED" read-only="true"/>
再有一般dao层采用currentSession的目的就是为了 不占用内存空间 尽量采用已有的session。所以一般都采用一个session
希望对你有所帮助~
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询