# Spring事务 手动开启事务 @Transactional详解

Spring事务 @Transactional详解


  • 思考:在一些很重要的地方,例如银行存钱的时候,假如你的钱已经进入了Atm中但是,后面你查询余额的时候发现,你的钱并没有存进去。假如你给某人转账,你的账户显示转账成功,但是对方并没有收到钱,这种重要的操作就应该考虑使用事务操作。

事务管理方式

编程式事务管理

使用TransactionTemplate或者使用底层的PlatformTransactionManager

声明式事务管理

声明式事务建立在AOP之上,对方法前后进行拦截,然后方法开始之前创建或者加入一个事务,在执行完目标方法后更具执行情况提交或者回滚事务。声明式事务一种基于tx和aop的xml配置文件,另一种是基于@Transactional注解。


@Transactional注解使用说明

  • 当作用于类上时候,该类的所用Public方法都将具有该类型的事务属性。
  • 方法加上@Transactional(rollbackFor=Exception.class)肯定会回滚。
  • 如果@Transactional不加属性那么事务只有在遇到RuntimeException的时候才会回滚。

@Transactional回滚Or不回滚

try catch捕获异常
  • 在执行的过程中,异常被捕获了所以,无法进行回滚。
@RequestMapping("/test1")
@Transactional(rollbackFor = Exception.class)
public String test1() {
    try {
        Menu menu = new Menu();
        menu.setName("事务测试2");
        menu.setFlavor("事务测试2");
        menu.setPrice((double) 34);
        menu.setCount(23);
        menu.setId(2);
        menuRepository.update(menu);
        int a=10/0;
        return "sucess";
    } catch (Exception e) {
        e.printStackTrace();
        return "fail";
    }
}
  • 要想在try catch中也能回滚操作,只需要在catch中加上如下的语句。此时不管有没有异常都会进行回滚操作。
@RequestMapping("/test1")
@Transactional(rollbackFor = Exception.class)
public String test1() {
    try {
        menuRepository.update(menu);
        int a=10/0;
        return "sucess";
    } catch (Exception e) {
        e.printStackTrace();
        //只要抛异常则回滚
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        return "fail";
    }
}
不捕获异常
  • @Transaction加上roolbackfor参数,会进行回滚操作。
@RequestMapping("/test2")
@ApiOperation(value = "事务回滚测试2", notes = "不捕获异常不抛出异常")
@Transactional(rollbackFor = Exception.class)
public String test2() {
    menuRepository.update(menu);
    int a = 10 / 0;
    return "sucess";
}
  • 抛出RuntimeException,事务进行回滚
@RequestMapping("/test3")
@ApiOperation(value = "事务回滚测试3", notes = "不加参数")
@Transactional
public String test3() {
    menuRepository.update(menu);
    int a = 10 / 0;
    throw new RuntimeException();
}
  • 抛出其他异常事务不回滚
@RequestMapping("/test3")
@Transactional
public String test4() {
    menuRepository.update(menu);
    int a = 10 / 0;
    throw new ArithmeticException();
}

SpringBoot 手动和自动管理事务

手动

@Api("事务手动提交测试")
@RestController
@RequestMapping("/thing")
public class TransactionsController {

    @Autowired
    MenuRepository menuRepository;
    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;


    @RequestMapping("/test1")
    @ApiOperation(value = "事务回滚测试1", notes = "加上Transactional的属性")
    public String test1() {
        TransactionStatus transactionStatus = null;
        try {
            //手动开启事务
            transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
            Menu menu = new Menu();
            menu.setName("事务测试2");
            menu.setFlavor("事务测试2");
            menu.setPrice((double) 34);
            menu.setCount(23);
            menu.setId(2);
            menuRepository.update(menu);
            //手动提交事务
            dataSourceTransactionManager.commit(transactionStatus);
            int a = 10 / 0;
            return "sucess";
        } catch (Exception e) {
            if (transactionStatus != null) {
                //手动回滚
                dataSourceTransactionManager.rollback(transactionStatus);
            }
            e.printStackTrace();
            return "fail";
        }
    }
}

自动

见上面的@Transactional的用法

猜你喜欢

转载自blog.csdn.net/qq_37248504/article/details/107008217
今日推荐