按照三层体系结构,持久层的CRUD操作封装在DAO中,但并不负责事物处理,把事物留在service层来做。在使用Spring框架的情况下,spring会使用基于AOP的事物代理工厂来拦截显示层对服务层方法的调用,在每一个服务层(业务逻辑层)的方法前后自动加上事物处理。

解决方案 »

  1.   

    感谢IceCraft,不过如果不使用Spring框架呢?
    我在dao层封装hibernate,在业务逻辑层调用,如果象你所说的,那么在业务逻辑层还是要用到hibernate.session,这样是不是不好?这个问题一直想不通阿,好像在网上所看到的代码示例中都在dao层就包含了事务,但是业务和事务应该是分不开的吧?
      

  2.   

    欢迎光临我的博客http://drivemewild.bokee.com/
      

  3.   

    既然要在业务层调用事物,那应该就要用到hibernate.session了。即便是spring的AOP事务管理,也是让事物代理工厂自动去调用hibernate来操作事物。不过应为spring都是面向接口的,通过依赖注射的方式,所以可以很方便的更换DAO的实现,比如你可以直接使用JDBC来实现你的DAO,spring的事物代理工厂也会自动的调用JDBC来控制事物,而你无需修改业务层的代码。但如果你没有用spring,就直接在业务层直接调用hibernate.session进行事物,当你用JDBC实现DAO时,就不得不修改业务层代码来调用JDBC进行事物。
    你所看到的那些在dao层就包含事物的代码对事物的控制应该就比较弱了。比如一次业务逻辑中需要调用多个DAO的多个方法,一旦其中某个DAO的方法失败造成回滚,则已经执行了的那些DAO方法将无法回滚,就不能真正算是事物控制了。
    所以你可以考虑使用spring框架,或者直接在业务层调用一些事物类来处理事物。
      

  4.   

    在业务层基本上是不用调用hibernate.session的,
    可以对hibernate的事务进行自我封装,与dao类似
    这样就可以避免以后如果不用hibernate的时候,可以只改动dao层的代码
    而service层的代码没有任何改动
    可以参照aop的方式进行处理
    代码可以更好的重用
      

  5.   

    我原先也考虑对Hibernate进行封装,然后就使用自己的封装类,这样在更换Hibernate的时候也方便。不过后来想更换Hibernate的可能性较小,所有对Hibernate进行封装的必要性就不大了。我是在.net环境下用NHibernate的。还有一个hibernate的问题,就是在加载类的时候,是否可以动态设置所加载类的对象层次。我看一本资料说ObjectSpaces是可以的,但是hibernate的官方文档上好像没有明确说明。
      

  6.   

    引用:你所看到的那些在dao层就包含事物的代码对事物的控制应该就比较弱了。比如一次业务逻辑中需要调用多个DAO的多个方法,一旦其中某个DAO的方法失败造成回滚,则已经执行了的那些DAO方法将无法回滚,就不能真正算是事物控制了。所以service层控制事物比较好,而且用springAOP来做这个事情很方便,只需十多行代码即可搞定