您的位置:程序门 -> java -> j2ee / ejb / jms



求教解决一个spring事务的回滚问题


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


求教解决一个spring事务的回滚问题
发表于:2007-03-22 18:34:56 楼主
spring   +   hibernate   +   oracle   10g,采用声明型事务,在insertbrand()方法中执行批量insert语句,前3条成功执行,第四条抛出异常,按理说事务应该回滚,把前三条插入的取消,但打开数据库表却发现没有取消,请各位大虾看看那里弄错了。代码如下:
1.spring的配置文件:
<!--   dao   -->
<bean   id= "hdao "   class= "com.reedar.web.dao.impl.hreedardaoimpl ">
<property   name= "sessionfactory ">
<ref   bean= "sessionfactory "   />
</property>
</bean>
       
<bean   id= "producttarget "   class= "com.reedar.web.ds.impl.productimpl ">
                <property   name= "reedardao ">
                        <ref   bean= "hdao "/>
                </property>
</bean>

<bean   id= "transactionmanager "
                class= "org.springframework.orm.hibernate3.hibernatetransactionmanager ">
                <property   name= "datasource ">
                        <ref   local= "datasource "/>
                </property>
                <property   name= "sessionfactory ">
                        <ref   local= "sessionfactory "/>
                </property>
</bean>

<bean   id= "product "
class= "org.springframework.transaction.interceptor.transactionproxyfactorybean ">  
                <property   name= "target ">
                        <ref   local= "producttarget "/>
                </property>
                <property   name= "transactionmanager ">
                <ref   bean= "transactionmanager "/>
                </property>
                <property   name= "transactionattributes ">
                <props>
                <prop   key= "get* "> propagation_supports,readonly </prop>
                <prop   key= "add* "> propagation_required </prop>
                </props>
                </property>
        </bean>
2.   业务实现类及接口
public   interface   productservice   extends   baseservice{
public   boolean   addbrand(brand   brand);
}

public   class   productimpl   implements   productservice{
public   boolean   addbrand(brand   brand)   {
try{
reedardao.saveorupdatedomain(brand);
}catch(exception   ex){
return   false;
}
return   true;
}
}

3.测试代码
public   class   prodtypetest   extends   testcase   {
protected   void   setup()   throws   exception   {
super.setup();
applicationcontext   context=new   filesystemxmlapplicationcontext( "src/applicationcontext.xml ");
product=   (productservice)context.getbean( "product ");
}

public   void   testsave(list   list)   {     //list中有一个对象违反数据库的非空约束;
try{
iterator   iter   =   list.iterator();

while(iter.hasnext()){

brand   obj   =   (brand)iter.next();
ps.addbrand(obj);
}
}catch(exception   e){
e.printstacktrace();
}
4.执行情况
抛出异常,但非法对象前面的对象均已插入数据库,说明事务没有回滚,再补充说明一下:在spring的配置文件中,已经将datasource设为:
<property   name= "defaultautocommit "> <value> false </value> </property>

抛出的异常如下:
error   abstractflushingeventlistener:277   -   could   not   synchronize   database   state   with   session
org.hibernate.exception.constraintviolationexception:   could   not   EXECute   jdbc   batch   update
at   org.hibernate.exception.errorcodeconverter.convert(errorcodeconverter.java:74)
at   org.hibernate.exception.jdbcexceptionhelper.convert(jdbcexceptionhelper.java:43)
at   org.hibernate.jdbc.abstractbatcher.EXECutebatch(abstractbatcher.java:181)
at   org.hibernate.engine.actionqueue.EXECuteactions(actionqueue.java:226)
at   org.hibernate.engine.actionqueue.EXECuteactions(actionqueue.java:136)
at   org.hibernate.event.def.abstractflushingeventlistener.performEXECutions(abstractflushingeventlistener.java:274)
at   org.hibernate.event.def.defaultflusheventlistener.onflush(defaultflusheventlistener.java:27)
at   org.hibernate.impl.sessionimpl.flush(sessionimpl.java:730)
at   org.hibernate.impl.sessionimpl.managedflush(sessionimpl.java:324)
at   org.hibernate.transaction.jdbctransaction.commit(jdbctransaction.java:86)
at   org.springframework.orm.hibernate3.hibernatetransactionmanager.docommit(hibernatetransactionmanager.java:490)
at   org.springframework.transaction.support.abstractplatformtransactionmanager.processcommit(abstractplatformtransactionmanager.java:495)
at   org.springframework.transaction.support.abstractplatformtransactionmanager.commit(abstractplatformtransactionmanager.java:468)
at   org.springframework.transaction.interceptor.transactionaspectsupport.docommittransactionafterreturning(transactionaspectsupport.java:258)
at   org.springframework.transaction.interceptor.transactioninterceptor.invoke(transactioninterceptor.java:106)
at   org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:144)
at   org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:174)
at   $proxy1.addbrand(unknown   source)
at   com.reedar.web.pub.util.excelfilereader.saveobject(excelfilereader.java:254)
at   com.reedar.web.pub.util.excelfilereader.main(excelfilereader.java:44)
caused   by:   java.sql.batchupdateexception:   ora-01400:   cannot   insert   null   into   ( "dev ". "tab_brand ". "language ")

at   oracle.jdbc.driver.databaseerror.throwbatchupdateexception(databaseerror.java:367)
at   oracle.jdbc.driver.oraclepreparedstatement.EXECutebatch(oraclepreparedstatement.java:8738)
at   org.apache.commons.dbcp.delegatingstatement.EXECutebatch(delegatingstatement.java:294)
at   org.hibernate.jdbc.batchingbatcher.doEXECutebatch(batchingbatcher.java:57)
at   org.hibernate.jdbc.abstractbatcher.EXECutebatch(abstractbatcher.java:174)
...   17   more
org.springframework.dao.dataintegrityviolationexception:   hibernate   operation:   could   not   EXECute   jdbc   batch   update;   sql   [insert   into   dev.tab_brand   (brandname,   language,   prep_1,   prep_2,   brandid)   values   (?,   ?,   ?,   ?,   ?)];   ora-01400:   cannot   insert   null   into   ( "dev ". "tab_brand ". "language ")
;   nested   exception   is   java.sql.batchupdateexception:   ora-01400:   cannot   insert   null   into   ( "dev ". "tab_brand ". "language ")

java.sql.batchupdateexception:   ora-01400:   cannot   insert   null   into   ( "dev ". "tab_brand ". "language ")

at   oracle.jdbc.driver.databaseerror.throwbatchupdateexception(databaseerror.java:367)
at   oracle.jdbc.driver.oraclepreparedstatement.EXECutebatch(oraclepreparedstatement.java:8738)
at   org.apache.commons.dbcp.delegatingstatement.EXECutebatch(delegatingstatement.java:294)
at   org.hibernate.jdbc.batchingbatcher.doEXECutebatch(batchingbatcher.java:57)
at   org.hibernate.jdbc.abstractbatcher.EXECutebatch(abstractbatcher.java:174)
at   org.hibernate.engine.actionqueue.EXECuteactions(actionqueue.java:226)
at   org.hibernate.engine.actionqueue.EXECuteactions(actionqueue.java:136)
at   org.hibernate.event.def.abstractflushingeventlistener.performEXECutions(abstractflushingeventlistener.java:274)
at   org.hibernate.event.def.defaultflusheventlistener.onflush(defaultflusheventlistener.java:27)
at   org.hibernate.impl.sessionimpl.flush(sessionimpl.java:730)
at   org.hibernate.impl.sessionimpl.managedflush(sessionimpl.java:324)
at   org.hibernate.transaction.jdbctransaction.commit(jdbctransaction.java:86)
at   org.springframework.orm.hibernate3.hibernatetransactionmanager.docommit(hibernatetransactionmanager.java:490)
at   org.springframework.transaction.support.abstractplatformtransactionmanager.processcommit(abstractplatformtransactionmanager.java:495)
at   org.springframework.transaction.support.abstractplatformtransactionmanager.commit(abstractplatformtransactionmanager.java:468)
at   org.springframework.transaction.interceptor.transactionaspectsupport.docommittransactionafterreturning(transactionaspectsupport.java:258)
at   org.springframework.transaction.interceptor.transactioninterceptor.invoke(transactioninterceptor.java:106)
at   org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:144)
at   org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:174)
at   $proxy1.addbrand(unknown   source)
at   com.reedar.web.pub.util.excelfilereader.saveobject(excelfilereader.java:254)
at   com.reedar.web.pub.util.excelfilereader.main(excelfilereader.java:44)
发表于:2007-03-22 19:38:501楼 得分:0
在你的配置中只对get、add的方法做了事务说明,而没有对insertbrand()方法做事务说明,所以导致以上结果。加入即可。
发表于:2007-03-22 19:50:332楼 得分:0
spring   配置文件对事务应用方法的说明,不是针对代理类的target中的方法而言的吗?应该与测试代码的方法名没有关系。
发表于:2007-03-22 20:35:403楼 得分:0
sorry,刚才没看清楚,是由于你的addbrand()方法是针对每一个brand对象做saveorupdate的,所以也就是对每个brand对象都是一个事务,当你在testcase中作批处理时就会产生以上结果了。
发表于:2007-03-22 20:43:234楼 得分:0
再请教一下,如果在此情况下,我想回滚,该如何修改呢?
发表于:2007-03-22 23:41:175楼 得分:0
你应该将批量处理放入addbrand()方法中,这样在这个批量中如果有一个错误,则整批就会回滚。


快速检索

最新资讯
热门点击