spring(基础七) spring事务回滚详解

(一) 用编程的方法来实现,我觉得这种方法比较灵活,控制起来比较方便,但是需要写一些额外的代码

1.1 定义bean:

<!--定义Bean-->
    <bean id="Test" class="com.test.Test">
        <property name="template" ref="jdbcTemplate" />
        <property name="transaction" ref="transactionTemplate" />
    </bean>
 

1.2 事务配置:
<!--事务模板 -->  
  <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">  
           <property name="transactionManager">  
                    <ref local="transactionManager"/>  
           </property>  
  </bean> 
<!-- jdbc事务管理器 -->  
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
           <property name="dataSource">          
            <ref local="dataSource"/>  
   </property>

1.3 测试类
public class Test {
    private JdbcTemplate template;
    private TransactionTemplate transaction;
    private static final String TEST_SQL="insert into user(name,date) values(?,?)";
    public void setTemplate(JdbcTemplate template) {
        this.template = template;
    }

    public void setTransaction(TransactionTemplate transaction) {
        this.transaction = transaction;
    }
    public  void testSQL() throws Exception{
        for(int i=0;i<10;i++){
            if(i==8)throw new Exception("====error when updaa=======");//到第八条数据时我抛异常
            template.update(TEST_SQL,new Object[]{"xugang"+i,"123"});
        }
       
    }
    public static void main(String[] args) throws Exception{
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        final Test t=(Test)ctx.getBean("Test");
        boolean f=t.transaction.execute(new TransactionCallback<Boolean>() {
            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                    try {    
                        t.testSQL();//测试SQL
                        return Boolean.TRUE;//插入成功
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        status.setRollbackOnly();//回滚事物
                        e.printStackTrace();
                        return Boolean.FALSE;
                    }
            }
        });
}



(二)用声明的方法来实现事物的管理,在配置文件中加入下面

 <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" /><!--以get开头的方法中的Connection是readonly的 -->
            <tx:method name="update*" rollback-for="Throwable"/><!-- 在update开头的方法中遇到异常(Throwable)就回滚-->
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut expression="execution(* com.test.Test2.*(..))"<!-- 匹配com.test.Test2这个类下面的所有方法-->
            id="service" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="service" />
    </aop:config>

/**
 * 测试事物回滚
 * @author 许刚
 */
public class Test2 {
    private JdbcTemplate template;
    private TransactionTemplate transaction;
    private static final String TEST_SQL="insert into user(name,date) values(?,?)";
    public void setTemplate(JdbcTemplate template) {
        this.template = template;
    }

    public void setTransaction(TransactionTemplate transaction) {
        this.transaction = transaction;
    }
    public  void testSQL() throws Exception{
        for(int i=0;i<10;i++){
            if(i==8)throw new Exception("====error when updaa=======");
            template.update(TEST_SQL,new Object[]{"xugang"+i,"123"});
        }
        
    }
    
    public void getData(){
        template.update(TEST_SQL,new Object[]{"xugang","123"});
    }
    public void updateData() throws Exception{
        testSQL();
    }    
    public static void main(String[] args) throws Exception{
        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
        final Test2 t=(Test2)ctx.getBean("Test2");
        //t.getData();//get开头的方法是readonly的就会抛下面的异常
        //  java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
        t.updateData();//执行玩了以后,数据库里面一条数据都没有的,在第8条的时候回滚了
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring框架中,事务的传播性是指在一个方法中调用另一个方法时,事务应该如何进行传播。其中,REQUIRED是Spring事务传播性最常用的一种类型。下面是对REQUIRED事务传播性的详细解释: 1. 如果当前方法已经在一个事务中,则调用的方法将在同一个事务中运行。如果调用的方法发生异常并抛出了异常,则整个事务将回滚。 2. 如果当前方法没有在一个事务中,则调用的方法将开启一个新的事务并在其中运行。如果调用的方法发生异常并抛出了异常,则整个事务将回滚。 3. 如果当前方法没有在一个事务中,但调用的方法标有@Transactional注解并且使用REQUIRED传播性,则调用的方法将加入当前方法所在的事务中。 4. 如果当前方法已经在一个事务中,但调用的方法标有@Transactional注解并且使用REQUIRED_NEW传播性,则当前方法的事务将被挂起,调用的方法将在一个新的事务中运行。如果调用的方法发生异常并抛出了异常,则只有调用方法所在的事务会回滚,当前方法所在的事务不会回滚。 总之,使用REQUIRED传播性可以确保方法在一个事务中运行,同时保证整个事务的一致性和完整性。但需要注意的是,如果方法的执行时间过长,可能会导致事务锁定时间过长,从而影响系统性能。因此,在使用Spring事务时,应该根据具体情况选择合适的事务传播性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值