<!--为业务逻辑Bean配置事务代理 -->
<bean id="testTrans" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="test"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>在业务逻辑Bean的方法中有一个insert方法,其中会分别保存两行数据,第一行数据是能成功保存的,第二行数据在程序执行中是会包异常的,由于有Spring 的事务管理,这个时候应该会执行事务回滚,但是实际上我的第一行数据还是被保存了!说明事务管理失效了,这该如何解决了???

解决方案 »

  1.   

    出现这种问题的原因太多了,
    首先 你的Service 是不是注入的 你配置的这个事务 testTrans、是不是把RuntimeException在方法中跑出来了,不要catch掉。
      

  2.   

    异常没有catch掉的,testTrans是代理bean,我用这个方法直接获得的,然后调用实际Bean的insert方法ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
    Test t = (Test)ctx.getBean("testTrans");
      

  3.   

    Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked 如果遇到checked意外就不回滚。 如何改变默认规则: 1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class) 2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class) 3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)  注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}。  spring——@Transactional事务不管理jdbc,所以要自己把jdbc事务回滚。
      

  4.   

    从别处copy过来的东西,连改都懒得改下,你怎么好意思发过来?
      

  5.   

    我++
       哥啊.....我现在跟你一样事务不启效果啊!!!
    我想问一下..都把异常抛到service层来了..还不catch掉的话..那怎么办???还往上抛?
      

  6.   

    service层的异常往外抛,在action层捕获异常,service层调用的dao层的代码就会回滚了
      

  7.   

    <bean id="superDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
         <property name="transactionManager" ref="tranMager"/>
          1.2事务管理规则
         <property name="transactionAttributes">
         <props>
    <prop key="add*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
    <prop key="update*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
    </props>
         </property>
        </bean>
    这是我的事务你看看吧,我这个事务大概的意思是,管理以add开头,update开头的方法,-java.lang.Exception为管理事务的异常类型,其他方法都为只读方法<bean id="bookBizPro" parent="superDao">
         <property name="target" ref="bookBiz"></property>
        </bean>这是事务管理的业务类
    当你注入到action中的话只能用bookBizPro,如果你用bookBiz是没有事务管理的
      

  8.   

    我以前也遇到过类似的,结果发现是mysql的问题。不知道你用的是数据库是不是mysql,因为默认表类型是MyISAM不支持事务管理的,要改为InnoDB才行。
      

  9.   


    我xml的配置也是你这样的配的!~~麻烦你把java代码也贴出来 下吧...谢谢
      

  10.   

    楼主说了业务逻辑Bean的方法中有一个insert方法,会分别保存两行数据;
    不知道业务逻辑Bean是Service层中的bean还是个DAO?
    Spring的事务应该配置在Service的bean中;示例:
    TestServiceImpl{
        TestDao testDao;
        public void insert(){
           testDao.save();//success
           testDao.save();//fail
        }
    }最后是上面说的异常和数据库问题,需要一一排除;
      

  11.   

    我实在是找不到问题出在哪了!!!我把我所有的代码贴上来吧,望高人解决啊!
    bean.xml<?xml version="1.0" encoding="GBK"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
    "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
    <beans>
    <!--定義數據源Bean,使用C3P0數據源實現-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost/test"/>
    <property name="user" value="root"/>
    <property name="password" value="1234"/>
    <property name="maxPoolSize" value="40"/>
    <property name="minPoolSize" value="1"/>
    <property name="initialPoolSize" value="1"/>
    <property name="maxIdleTime" value="20"/>
    </bean>
    <!--配置JDBC數據源的局部事務管理器,使用DataSourceTrannsactionManager類 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="test" class="spring.TestImpl">
    <property name="ds" ref="dataSource"/>
    </bean>

    <!--配置一个业务逻辑组件 -->
    <bean id="myService" class="spring.MyServiceImpl">
    <!--将DAO组件注入给业务逻辑组件-->
    <property name="test" ref="test"/>
    </bean> <!--為業務邏輯Bean配置事務代理 -->
    <bean id="testTrans" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="target" ref="myService"/>
    <property name="transactionAttributes">
    <props>
    <prop key="insert*">PROPAGATION_REQUIRED</prop>
    </props>
    </property>
    </bean>
    </beans>
    TestImpl.java实现了Test这个接口(这是DAO),里面就一个insert方法,package spring;import javax.sql.DataSource;import org.springframework.jdbc.core.JdbcTemplate;public class TestImpl implements Test { private DataSource ds; public void setDs(DataSource ds) {
    this.ds = ds;
    }
    public void insert(int i) {
    // TODO Auto-generated method stub
    JdbcTemplate jt = new JdbcTemplate(ds);
    jt.execute("insert into mytable value("+i+")");
    }
    }
    MyServiceImpl.java是业务逻辑类,实现了MyService接口,注入了Test(DAO)package spring;public class MyServiceImpl implements MyService{

    private Test test;
    public void setTest(Test test) {
    this.test = test;
    }
    @Override
    public void insert(int id) {
    // TODO Auto-generated method stub
    test.insert(id);
    test.insert(id);
    }
    }MainTest.java是一个测试类package spring;import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainTest {
    public static void main(String arg[])throws Exception {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
    MyService t = (MyService)ctx.getBean("testTrans");
    t.insert(1);
    }
    }运行后出报异常,我不关心这个异常,我只希望数据库中应该是没有数据的,可事实是insert成功了一个。
      

  12.   

    数据库名:test
    表名:mytable
    表中就一个字段:id (int型 primary key)
      

  13.   

    只一个疑问:
    JdbcTemplate jt = new JdbcTemplate(ds);
    是不是Spring受管的对象?
      

  14.   

    我发现很有可能还是MySQL的问题,表的类型如果为MyISAM的话是不支持事务管理的,你看你的表类型是不是这个。
    我的MySQL版本是5.1.X(好像不支持InnoDB表类型) 虽然MySQL中的my.ini文件中default-storage-engine=INNODB
    但是建表时默认的还是MyISAM,改成INNODB就会报错。我现在在考虑这个问题了。你可以修改以下表类型试试。
      

  15.   

     <prop key="insert*">PROPAGATION_REQUIRED</prop>你加上异常类型看看
    <prop key="add*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>这好像这样