我的工程中事务采用spring声明式事务,配置如下: 
<bean id="souDAO" 
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
<property name="transactionManager"> 
<ref bean="transactionManager" /> 
</property> 
<property name="target"> 
<ref bean="souDAOBase" /> 
</property> 
<property name="transactionAttributes"> 
<props> 
<prop key="*get*">PROPAGATION_REQUIRED,readOnly</prop> 
<prop key="*find*">PROPAGATION_REQUIRED,readOnly</prop> 
<prop key="*load*">PROPAGATION_REQUIRED,readOnly</prop> 
<prop key="*save*">PROPAGATION_REQUIRED</prop> 
<prop key="*add*">PROPAGATION_REQUIRED</prop> 
<prop key="*update*">PROPAGATION_REQUIRED</prop> 
<prop key="*delete*">PROPAGATION_REQUIRED</prop> 
<prop key="*write*">PROPAGATION_REQUIRED</prop> 
</props> 
</property> 
</bean> 在我的service中有方法如下: 
public void merImportadd1(MMmsMchntInfTmp mmmsmchntinftmp,MRequest mRequest,MAudit mAudit) throws Exception 

souDao.save(mmmsmchntinftmp); 
souDao.save(mRequest); 
mAudit.setRequetid(mRequest.getRequestid()); 
souDao.save(mAudit); 

运行时,此行抛出异常:souDao.save(mRequest); 
但此行调用成功:souDao.save(mmmsmchntinftmp); 数据库中保存成功。 
控制台异常如下: 
13:11:29,109 ERROR JDBCExceptionReporter : Data truncation: Data too long for column 'operator' at row 1 
13:11:29,109 ERROR AbstractFlushingEventListener : Could not synchronize database state with session 
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update 
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103) 
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91) 
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) 
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249) 
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235) 
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139) 
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297) 
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) 
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:993) 
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:340) 
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106) 
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:540) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:510) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:275) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:209) 
at $Proxy1.save(Unknown Source) 
at com.service.Mer.MerTmpServiceImpl.merImportadd1(MerTmpServiceImpl.java:58) 
第一个save方法执行成功,第二个save方法执行失败,但查看数据,第一个save保存的数据已经存在,的就是说,事务没有起作用,没有回滚。看了其它配置,都没发现什么问题。请问各位大侠,是哪方面原因? 

解决方案 »

  1.   

    由于你用的同一个souDao,第2个save运行正确,说明你的配置没有问题,问题可能出现在你传入的参数有问题,而且提示Data too long for column 'operator' at row 1说明你的对象MRequest,和Database 对应的列可能存在数据不匹配的问题。
      

  2.   

    spring不会对所有的异常进行rollback,通常只对runtimeException等几种有限的异常rollback,对于自定义的异常,若要进行回滚,需在配置文件中申明。就在<props>段中,在PROPAGATION_REQUIRED后加上需要回滚的异常类型即可。具体可参看spring   reference。
      

  3.   

    楼上的,你没有看明白吧,我是想测试spring的事物管理。
    souDao.save(mmmsmchntinftmp); 
    souDao.save(mRequest); 
    是第一行执行成功,第二行执行失败,问题是:第一行的执行没有回滚。
    不用关心提示:Data too long for column 'operator' at row,  这个是我故意设置对象属性长度超过数据库字段长度的,就是因为这个才执行失败的。
      

  4.   

    就是说你后台的异常不是runtimeException等几种有限的异常,事务不能识别,因此不会回滚.你把后台异常封装一下,抛一个runtimeException试试.
      

  5.   

    我的dao的save方法:
    public void save(final Object entity) throws DAOException {
    try {
    getHibernateTemplate().save(entity);
    } catch (HibernateException he) {
    log.debug(he.getCause());
    throw DAOException.getInstance(he.getCause());
    }
    }我的DAOException
    public class DAOException extends RuntimeException {
    ......
    }
      

  6.   

    是不是 getHibernateTemplate().save(entity); 本身会自动提交的原因?
      

  7.   

    看你的配置,没发现service类merImportadd1与transactionAttributes有什么关联配置,所以应该不会事务控制