前言:什么是事务呢?

事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

事务中最重要的一个特性就是原子性,它指的是在程序执行过程中,要么全部执行,要么都不执行,不存在执行其中的一部分,剩下的不执行的情况。



一。没有开启事务的例子

1.我在这里举一个例子说明,假设第一次操作与第二次操作有关联性,我们需要把第一次操作和第二次操作都完成,在第一次操作与第二次操作中间模拟出错,在不开启事务的情况下,看看结果如何,控制器代码如下:

    @GetMapping("/testTransactional")
    public Object testTransactional(){
        //第一次操作
        StudyNote studyNote=new StudyNote();
        studyNote.setContent("事务测试第一次操作");
        studyNoteService.save(studyNote);
        //模拟出错
        String s[]=new String[3];
        System.out.println(s[10]);
        //第二次操作
        studyNote.setContent("事务测试第二次操作");
        studyNoteService.save(studyNote);
        return ResponseUtil.ok();
    }

2.用postman测试该接口,报错数组下标越界异常,但是操作一执行成功,操作二没有执行:

在这里插入图片描述

3.操作一的数据成功插入到数据库中:

在这里插入图片描述

4.以上例子就是不开启事务的后果,具有关联性的操作一操作二只执行了其中的操作一,对于程序来说,这是一个很恐怖的事情。假如我将上面的例子类比为我们平时常见的网上购物,操作一为扣款,操作二为完善订单信息,中间的模拟操作为突然断网了。不开启事务的情况下,如果我们交易扣款的时候突然断网了,那么就会导致我们账户里的钱扣了,但是却查询不到任何的订单信息,这个是相当恐怖的!要是真的这么干的话,到时候可就不是笑笑就完事了,有可能要警察叔叔要管你饭了。

在这里插入图片描述

5.以下介绍开启事务的两种常见方式。

二。基于注解开启事务

只需要在方法头上加一个注解@Transactional即可:

    @Transactional
    @GetMapping("/testTransactional")
    public Object testTransactional(){
        //第一次操作
        StudyNote studyNote=new StudyNote();
        studyNote.setContent("事务测试第一次操作");
        studyNoteService.save(studyNote);
        //模拟出错
        String s[]=new String[3];
        System.out.println(s[10]);
        //第二次操作
        studyNote.setContent("事务测试第二次操作");
        studyNoteService.save(studyNote);
        return ResponseUtil.ok();
    }

在这里插入图片描述

三。基于代码开启事务

在需要开启事务的方法中,输入以下代码即可:

@Autowired
private PlatformTransactionManager txManager;

   // 开启事务管理
    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    TransactionStatus status = txManager.getTransaction(def);
    try {
         //操作都放在这里
    }catch(Exception e){
       //这里是异常处理
    }
    txManager.commit(status);//事务提交
    @GetMapping("/testTransactional")
    public Object testTransactional(){
        // 开启事务管理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = txManager.getTransaction(def);
        //操作都放在异常处理块中
        try {
            //第一次操作
            StudyNote studyNote=new StudyNote();
            studyNote.setContent("事务测试第一次操作");
            studyNoteService.save(studyNote);
            //模拟出错
            String s[]=new String[3];
            System.out.println(s[10]);
            //第二次操作
            studyNote.setContent("事务测试第二次操作");
            studyNoteService.save(studyNote);
        }catch (Exception e){
            //出现异常进行回退
            txManager.rollback(status);
            log.error("系统内部错误", e);
            return ResponseUtil.fail();
        }
        txManager.commit(status);//事务提交
        return ResponseUtil.ok();
    }
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐