锁定老帖子 主题:spring事务管理的控制问题
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-03-06
ahuaxuan 写道 terry_yip 写道 OK,如果我将事务管理放在service层,但是又要用spring和hibernate结合的方式对数据进行存取,各位如何建议我解决这个问题呢?
这里面根本就没有什么问题,你只要给service加上事务代理就ok了,不会有什么问题 如果我用JDBC的方法来连, 我可以connnection.commit()或connnection.rollback(); 如果用hibernate的方式来连接, Transaction tx = session.beginTransaction(); tx.commit();或tx.rollback(); 但用我以上的方式来连接数据库,是怎么rollback()或commit()呢? 其实我问题的核心就是在这个点上. |
|
返回顶楼 | |
发表时间:2007-03-06
terry_yip 写道 Godlikeme 写道 有没有service层?
Service层有没有设置transaction? 个人认为,应该在service层做这种事务控制。 有逻辑事务层, 我上面的public void update()方法,就是在相当于你说的service层做的,但问题是, 我再开一个transaction,怎样能控制当其中一个DaoProxy.update(bean)失败了,另一个update的操作rollback? 如果service层有事务控制,整个事务由最外层service层事务控制,propagation required. |
|
返回顶楼 | |
发表时间:2007-03-06
terry_yip 写道 ahuaxuan 写道 terry_yip 写道 OK,如果我将事务管理放在service层,但是又要用spring和hibernate结合的方式对数据进行存取,各位如何建议我解决这个问题呢?
这里面根本就没有什么问题,你只要给service加上事务代理就ok了,不会有什么问题 如果我用JDBC的方法来连, 我可以connnection.commit()或connnection.rollback(); 如果用hibernate的方式来连接, Transaction tx = session.beginTransaction(); tx.commit();或tx.rollback(); 但用我以上的方式来连接数据库,是怎么rollback()或commit()呢? 其实我问题的核心就是在这个点上. 如果是声明式事务处理,你只要抛出异常就自动rollback了,如果不抛异常,方法自动通过,那就commit了,不需要你手动的rollback何commit,这个就是声明式事务处理的优点之一 |
|
返回顶楼 | |
发表时间:2007-03-06
Godlikeme 写道 如果service层有事务控制,整个事务由最外层service层事务控制,propagation required. 你的意思, 是不是这样, 例如 我再写多一个CompleteDao类, 然后加入类似方法 public void updateBoth() { xxDao.update(bean); xxBackupDao.update(bean) } 然后, 在配置文件中, <bean id="CompleteDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref local="transactionManager"/> </property> <property name="target"><ref local="CompleteDao"/></property> <property name="transactionAttributes"> <props> <prop key="updateBoth">PROPAGATION_REQUIRED</prop> </props> </property> </bean> 是不是这样? |
|
返回顶楼 | |
发表时间:2007-03-06
是这样的,但是很少有人在dao上做事务控制的,应该是CompleteService类才对,理论上讲我们不应该在持久层做事务控制,应该在业务层(极少数情况除外),楼主对事务的概念非常模糊,建议去系统的看看相关的书籍
|
|
返回顶楼 | |
发表时间:2007-03-06
有个问题我不明白, 很多人都说我不应在DAO层做事务管理, 我也认同这个说法,但是,我觉得我是被spring和hibernate结合的方式逼着我这样做的, 因为这种结合方式本身就带"自动"的事务管理机制了. 不知是否我的那个配置文件的bean的名字带有DAO误导了大家,还是我真的有什么别的方法不知道,难道我应该把那个spring默认的事务管废掉,自己写commit, rollback吗? 如果是这样的话, 那我这部分直接用hibernate做算了, 为何还要用spring+hibernate方法呢??请大家指点一下,或说说你们在项目中是怎么处理这个问题的.
|
|
返回顶楼 | |
发表时间:2007-03-06
TransactionProxyFactoryBean的target应该是业务对象,你需要做的就是把业务对象付给TransactionProxyFactoryBean的target,然后其他一样配置,这样,你的service就能享受声明式事务处理了,或者通过自动代理来简化声明式事务的配置也是可以的
|
|
返回顶楼 | |
发表时间:2007-03-06
terry_yip 写道 因为这种结合方式本身就带"自动"的事务管理机制了.
所谓的自动是不需要你写代码显式进行事务管理。但前提还是还你去手动配置,让Spring知道你哪里需要事务参与。没有说你用Spring配置了一个DAO,那么这个DAO就有了神奇的自动事务管理功能。 最简单的做法就是把你那两个DAO的事务配置去掉(还原从纯粹的Bean非代理Bean),再在Service加上事务代理即可。 这样完整配置下来,从Service开始到结束都是一个事务,两个DAO的操作属于同一个事务中的操作。简单有效,何乐而不为?干嘛要每个DAO配上事务,而且为每个DAO配事务极度不可取。 |
|
返回顶楼 | |
发表时间:2007-03-09
<property name="target"><ref local="userDao"/></property>
你的target指向的应该是service层的类,而不是直接的dao |
|
返回顶楼 | |
发表时间:2007-03-09
如下是我的代码:
<bean id="userManagerTarget" class="zzc.stu.service.impl.UserManagerImpl"> <property name="dao"> <ref local="userDAO"/> </property> </bean> <bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref local="myTransactionManager"/> </property> <property name="target"> <ref local="userManagerTarget"/> </property> <property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIRED</prop> <prop key="remove*">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean> |
|
返回顶楼 | |