事务边界问题

来源:互联网 发布:淘宝818活动 编辑:程序博客网 时间:2024/05/05 19:36
事务边界问题 
我们先回顾一下我们现在写的代码: 

 

可以看到我们现在写的代码是Dao层中每一个方法都有一个事务包围着. 

我们现在以银行同行转帐为例 
因为Dao层只涉及到与数据库的交互,所以转帐这个方法应该是在服务层,那么这个时候我们在服务层有一个转帐的方法供我们调用. 
可以看到程序结构的情况如下: 
Dao层: 

 

Service层: 

 

我们可以看到现在在服务层中的转帐方法需要调用Dao层的两个方法,但是请注意,Dao层的两个方法,每个方法都有事务包围.如果帐户减减调用成功, 帐户++的方法调用出错,回滚了,请问帐户减减这个方法会回滚吗? 

肯定不会,那么这个时候就会出现钱不见了的问题了? 

这个时候的解决方案是将事务的开始与提交移到服务层,那这个时候就可以解决这个问题 

 

这种解决方法叫OpenSessionInView模式,因为我们现在还没有学到Spring,不能给服务层的方法进行拦截过滤,但是我们可以给Sevlet进行过滤,利用过滤器的功能. 

看一下结构图 




使用getCurrentSession()来获取Session在Hibernate.cfg.xml中必须配置一个开关 
<!-- 确定以何种方式产生session--> 
<property name="current_session_context_class">thread</property> 
此开关的配置值有两个: thread, jta 
那么jta什么时候用呢?现在只理解即可,不需要掌握. 

我们以跨行转帐为例子 

 

我们知道招行和工行不可能是同一个数据库,这个时候跨行转帐方法中的事务就得维护两个数据库之间的数据同步,这个时候就涉及到分布式的处理,也叫分布式的事务,那么这个时候就得设置为jta了, jta叫分布式事务管理, Tomcat不支持分布式事务的功能, 只有大型的收费的WEB应用服务器才支持分布式的事务管理,如Weblogic,WebSharp…在这里我们只做一下简单的了解即可. 

再回头看上面的问题,当我们将session的事务开始与事务结束放大到了Action的范围,并且getCurrentSession()又能够保证我们在一个线程内操作的是一个session,那这个时候,在WEB环境下,我们就可以解决我们懒加载(lazy)的问题了. 
0 0