唉,本想用Spring的事务来使事务的管理更轻松,没想到这东西竟折磨了我好几天,那是相当的郁闷!可能是经验不足吧,不过把它搞懂后,还是瞒高兴的,写一点心得体会和大家分享,释放一下郁闷的心情!
用Spring的声明式事务来管理程序,还是很方便的。它主要应用了spring的aop的代理来实现的,在每个操作开始前启动事务,方法结束后,根据有无异常分别进行回滚和提交。
我遇到的问题是当操作抛出异常后,无法进行回滚。
项目用的是SSH,Hibernate也是用spring来代理。dao都继承HibernateDaoSupport。
下面是大概的代码:

public class daoImpl extends HibernateDaoSupport implements IDao ...
{

public void add(Object o) ...{
HibernateTemplate template = getHibernateTemplate();
template.save(o);
}

public void delete(Object o) ...{
HibernateTemplate template = getHibernateTemplate();
template.delete(o);
}

public void update(Object o) ...{
add(o);
delete(o);
}
}



public class bizImpl implements IBiz ...
{
private IDao dao;

public void setDao(IDao dao) ...{
this.dao = dao;
}

public IDao getDao() ...{
return dao;
}

public void add(Object o) ...{
dao.add(o);
}

public void delete(Object o) ...{
dao.delete(o);
}

public void update(Object o) ...{
dao.update(o);
}
}
这是配置文件:(只设计事务方面)
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<bean name="transactionProxyBean"
class
="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="target">
<ref bean="theBiz"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
当我调用biz.update(o);的时候,会进行2次操作,add一次,delete一次,如果这时候delete抛出异常,那么刚插入的记录就需要回滚。可是却回滚不了。
要让spring自动回滚:
1.这两个操作必须在同一个事务中。因为我将事务放到了业务层,所以自然数据层的两个操作必然在一个事务中。
2.spring默认只有当抛出RuntimeException的或它的子类的时候,才会自动回滚。否则,如果自定义了异常,需要在<prop key="add*">PROPAGATION_REQUIRED</prop>后用-号标明,告诉spring在碰到这个异常的时候也回滚,+号表示提交,比如<prop key="add*">PROPAGATION_REQUIRED, -MyException</prop >
可是我并没有抛出自己定义异常,而且程序抛出的异常是RuntimeException
3.事务的插入是否正确。以上两点都满足,可是还是无法回滚,看来是事务没有正确被插入到代码中。
看看配置文件,用的是org.springframework.transaction.interceptor.TransactionProxyFactoryBean,文档上的解释是:This class is a convenient alternative to a standard AOP
<bean name="transactionInterceptorBeanGroup"
class
="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="modify*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>UserManageBiz</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptorBeanGroup</value>
</list>
</property>
</bean>
没想到这样一分开就可以了。看来真是TransactionProxyFactoryBean的问题。它怎么就不行呢?由于对spring的了解不深,我也不清楚这是怎么回事,如果大家谁知道,请赐教。
真是太奇怪了!
用Spring的声明式事务来管理程序,还是很方便的。它主要应用了spring的aop的代理来实现的,在每个操作开始前启动事务,方法结束后,根据有无异常分别进行回滚和提交。
我遇到的问题是当操作抛出异常后,无法进行回滚。
项目用的是SSH,Hibernate也是用spring来代理。dao都继承HibernateDaoSupport。
下面是大概的代码:

public class daoImpl extends HibernateDaoSupport implements IDao ...
{
public void add(Object o) ...{
HibernateTemplate template = getHibernateTemplate();
template.save(o);
}
public void delete(Object o) ...{
HibernateTemplate template = getHibernateTemplate();
template.delete(o);
}
public void update(Object o) ...{
add(o);
delete(o);
}
}



public class bizImpl implements IBiz ...
{
private IDao dao;

public void setDao(IDao dao) ...{
this.dao = dao;
}
public IDao getDao() ...{
return dao;
}
public void add(Object o) ...{
dao.add(o);
}
public void delete(Object o) ...{
dao.delete(o);
}
public void update(Object o) ...{
dao.update(o);
}
}
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<bean name="transactionProxyBean"
class
="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="target">
<ref bean="theBiz"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
当我调用biz.update(o);的时候,会进行2次操作,add一次,delete一次,如果这时候delete抛出异常,那么刚插入的记录就需要回滚。可是却回滚不了。
要让spring自动回滚:
1.这两个操作必须在同一个事务中。因为我将事务放到了业务层,所以自然数据层的两个操作必然在一个事务中。
2.spring默认只有当抛出RuntimeException的或它的子类的时候,才会自动回滚。否则,如果自定义了异常,需要在<prop key="add*">PROPAGATION_REQUIRED</prop>后用-号标明,告诉spring在碰到这个异常的时候也回滚,+号表示提交,比如<prop key="add*">PROPAGATION_REQUIRED, -MyException</prop >
可是我并没有抛出自己定义异常,而且程序抛出的异常是RuntimeException
3.事务的插入是否正确。以上两点都满足,可是还是无法回滚,看来是事务没有正确被插入到代码中。
看看配置文件,用的是org.springframework.transaction.interceptor.TransactionProxyFactoryBean,文档上的解释是:This class is a convenient alternative to a standard AOP
ProxyFactoryBean
with a separate
TransactionInterceptor
definition.他将ProxyFactoryBean和TransactionInterceptor合二为一,完成了他们两个 的工作,可能是这出了问题。于是我把TransactionProxyFactoryBean拆开,用ProxyFactoryBean和TransactionInterceptor分别表示:
<bean name="transactionInterceptorBeanGroup"
class
="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="modify*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>UserManageBiz</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptorBeanGroup</value>
</list>
</property>
</bean>
真是太奇怪了!
1168

被折叠的 条评论
为什么被折叠?



