The @ transactional annotation does not take effect after the Spring boot atomikos is configured

Keywords: Spring SpringBoot Database

1, When using things in springBoot, it is found that the transaction is not executed normally and is not rolled back:

    @GetMapping("/addincome/1")
    @Transactional
    public String addIncome1(@RequestParam("name") String name, @RequestParam("amount") double amount) {

        try {
            User user = new User();
            user.setName(name);
            userMapper.insert(user);

            Income income = new Income();
            income.setUserId(user.getId());
            income.setAmount(amount);
            income.setOperateDate(new Timestamp(System.currentTimeMillis()));
            incomeMapper.insert(income);

            return RESULT_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            return RESULT_FAILED + ":" + e.getMessage();
        }
    }

    @GetMapping("/addincome/2")
    @Transactional
    public String addIncome2(@RequestParam("name") String name, @RequestParam("amount") double amount) {
        try {
            User user = new User();
            user.setName(name);
            userMapper.insert(user);

            this.throwRuntimeException();

            Income income = new Income();
            income.setUserId(user.getId());
            income.setAmount(amount);
            income.setOperateDate(new Timestamp(System.currentTimeMillis()));
            incomeMapper.insert(income);

            return RESULT_SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
            // return RESULT_FAILED + ":" + e.getMessage();
        }
    }

But there was no rollback.

Analysis:

The default spring transaction is rolled back only when an uncaughted RuntimeException occurs. spring aop exception capture principle: the intercepted method needs to throw an exception explicitly without any processing, so that the aop agent can catch the exception of the method and roll back. By default, aop only catches the exception of RuntimeException, but it can catch specific exception and roll back through configuration. In other words, try catch is not used in the service method, or throw new runtimeexcetpion() is added at the end of catch, so that the program exception can be caught by aop and rolled back.

terms of settlement:

1. First confirm that the database supports transactions. This is InnoDB.
Scheme 1: manual rollback. Add parameters to the annotation, such as @ transactional (rollback for = exception. Class)
Scheme II: as above analysis. MyException is changed to an exception that inherits RuntimeException. And continue to catch the exception and handle it in the service layer.
Scheme 3: the catch statement of the method in the service layer.
Add: TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); statement, manually rollback, so the upper layer does not need to handle exceptions.

Posted by FireDrake on Fri, 31 Jan 2020 00:10:12 -0800