您的位置:首页 > 编程语言 > Java开发

基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之十三:用Spring嵌套事务(Nested Transaction) 回滚并返回自定义Exception

2016-10-19 10:42 579 查看
目的 :

要实现事务回滚并且能返回自定义的Exception,

首先我们先试验一下在transaction里运行:

@Transactional
public class xxx {
/****
* 修改/删除/增加 Controller接口
* @param pvReq
* @param pvLogin
* @param pvLocale
* @return
* @throws Exception
*/
public JSONData updateList(CommonReqUpdBean pvReq,String pvLogin, Locale pvLocale) throws Exception {
JSONData lvRet=new JSONData();
try {
for (CommonReqUpdBean.DataBean bean : pvReq.data) {
switch (bean.action) {
case CommonReqUpdBean.ACTION_DELETE: {
mTjDistributionDao.removeById((String)bean.key.id.get("fj_distribute_list"));
break;
}
case CommonReqUpdBean.ACTION_EDIT: {
TjDistributionList lvRec=getDistributionList((String) bean.key.id.get("fj_distribute_list"), pvLocale,null);
CommonReqUpdBean.copySomeValuesToEntity(bean.data,lvRec, "fj_distribute_user","fj_part_rel_user");
update(lvRec, false, pvLogin,pvLocale);
break;
}
case CommonReqUpdBean.ACTION_INSERT: {
TjDistributionList lvRec=CommonReqUpdBean.getBean(bean.data, TjDistributionList.class);
TjDistributionList lvE = mTjDistributionDao.get(lvRec.getFjDistributeList());
if (lvE != null) {
lvRet.errCode = 1;
lvRet.errMsg = MessageSourceHelper.getMessage("common.exists_failed", null);
break;
}
update(lvRec, true, pvLogin,pvLocale);
break;
}
}
}
} catch (ModifyDataException e) {
mTjDistributionDao.clear();
mTjDistributionDao.getSession().getTransaction().rollback();
jsonDataFillErrMsg(lvRet, e);
throw e;
}
finally{
}
return lvRet;
}

...
}


运行之, 返回错误信息 "Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started", 这是由于updateList运行完毕后, 事务管理器会自动commit,但由于我在Catch exception时已经rollback,但是就触发起这个"意料之外"的Exception, 因为这样,也就不能正常回传
JSONDATA数据.

解决这个问题当然可以用上一节我们讲的新开一个session和transaction来操作, 但如果用当前session和transaction又如何解决呢? 这里要用到嵌套事务.

要嵌套事务能正常工作必须满足以下条件: 你的数据库支持检查点(用Connection.getMetaData().supportsSavepoints()测试下), 配置事务管理时要加上嵌套事务支持:

<!-- 定义事务管理 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="nestedTransactionAllowed">
<value>true</value>
</property>
</bean>


然后给updatelist方法加上注释:@Transactional(propagation=Propagation.NESTED, rollbackFor=ModifyDataException.class), 这个注释做了两个声明,一个是"这里新开一个嵌套事务", 另一个是"抛出ModifyException时事务管理器要回滚此嵌套的事务"

于是我们将代码改为:

/****
* 修改/删除/增加 Controller接口
* @param pvReq
* @param pvLogin
* @param pvLocale
* @return
* @throws Exception
*/
@Transactional(propagation=Propagation.NESTED, rollbackFor=ModifyDataException.class)
public JSONData updateList(CommonReqUpdBean pvReq,String pvLogin, Locale pvLocale) throws Exception {
JSONData lvRet=new JSONData();

//mTjDistributionDao.getSession().getTransaction().begin();
try {
for (CommonReqUpdBean.DataBean bean : pvReq.data) {
switch (bean.action) {
case CommonReqUpdBean.ACTION_DELETE: {
mTjDistributionDao.removeById((String)bean.key.id.get("fj_distribute_list"));
break;
}
case CommonReqUpdBean.ACTION_EDIT: {
TjDistributionList lvRec=getDistributionList((String) bean.key.id.get("fj_distribute_list"), pvLocale,null);
CommonReqUpdBean.copySomeValuesToEntity(bean.data,lvRec, "fj_distribute_user","fj_part_rel_user");
update(lvRec, false, pvLogin,pvLocale);
break;
}
case CommonReqUpdBean.ACTION_INSERT: {
TjDistributionList lvRec=CommonReqUpdBean.getBean(bean.data, TjDistributionList.class);
TjDistributionList lvE = mTjDistributionDao.get(lvRec.getFjDistributeList());
if (lvE != null) {
lvRet.errCode = 1;
lvRet.errMsg = MessageSourceHelper.getMessage("common.exists_failed", null);
break;
}
update(lvRec, true, pvLogin,pvLocale);
break;
}
}
}
//mTjDistributionDao.getSession().getTransaction().commit();
} catch (ModifyDataException e) {
mTjDistributionDao.clear();
//mTjDistributionDao.getSession().getTransaction().rollback(); 不用自己回滚,交给事务管理器做
jsonDataFillErrMsg(lvRet, e);
throw e;
}
finally{
}
return lvRet;
}


已成功将ModifyException回传至前端.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  事务 spring
相关文章推荐