preface

When we develop systems often meet some requirements about the transaction, transaction process most are more complicated (including changing inventory, modify, balance, record trade bills, etc.), then we have to consider the potential risks, for example, we modified the inventory in the process of trading (1) inventory, you need to pay, However, at this time, the system suddenly goes down or the network is suddenly interrupted, which leads to our inability to complete the whole transaction process. Although the users have not paid, our inventory is reduced (the merchants are definitely not happy ๐Ÿ‘ฟ), so we need to use transaction rollback to solve the above problems.

Spring Boot transaction rollback

Transactional rollback There are two ways to implement transaction rollback: automatic rollback and manual rollback. The two methods are similar. Both require the @Transactional annotation to implement transaction rollback.

There is a method to insert member information in the interface implementation class. Let’s modify this method to implement automatic rollback and manual rollback ๐Ÿ‘‡ respectively

/** * Insert member information **@paramInformation about cashierMember *@returnResults the * /
@Override
public int insertCashierMember(CashierMember cashierMember)
{
    cashierMember.setCreateTime(DateUtils.getNowDate());
    cashierMember.setCreateBy(ShiroUtils.getLoginName());
    SMSUtil.sendCreateMemberMessage(cashierMember.getPhonenumber());
    return cashierMemberMapper.insertCashierMember(cashierMember);
}
Copy the code

An automatic rollback

/** * Insert member information **@paramInformation about cashierMember *@returnResults the * /
@Override
@Transactional(rollbackFor = Exception.class)
public int insertCashierMember(CashierMember cashierMember)
{
    cashierMember.setCreateTime(DateUtils.getNowDate());
    cashierMember.setCreateBy(ShiroUtils.getLoginName());
    SMSUtil.sendCreateMemberMessage(cashierMember.getPhonenumber());
    return cashierMemberMapper.insertCashierMember(cashierMember);
}
Copy the code

You can see the Transactional annotation @Transactional(rollbackFor = exception.class) added to the method to catch exceptions and roll them back when they occur to undo the transaction.

Many methods handle an exception with a try-catch. If a possible exception is handled in the catch, but no more manual throws are thrown, Spring considers the method to have executed successfully and does not roll back ๐Ÿ‘‡.The correct solution is as follows ๐Ÿ‘‡ :

/** * Insert member information **@paramInformation about cashierMember *@returnResults the * /
@Override
@Transactional(rollbackFor = Exception.class)
public int insertCashierMember(CashierMember cashierMember)
{
    try {
        cashierMember.setCreateTime(DateUtils.getNowDate());
        cashierMember.setCreateBy(ShiroUtils.getLoginName());
        SMSUtil.sendCreateMemberMessage(cashierMember.getPhonenumber());
        return cashierMemberMapper.insertCashierMember(cashierMember);
    }catch (Exception e){
        System.out.println("Method error:" + e);
        // Manually throw an exception
        throw newRuntimeException(); }}Copy the code

P.S. If a try-catch statement returns ina finally block, the exception thrown manually in the catch block will be overwritten and will not be rolled back automatically.

Manual rollback

Manual rollback is also very easy to implement, just need to add a line of code to achieve ๐Ÿ‘‡

/** * Insert member information **@paramInformation about cashierMember *@returnResults the * /
@Override
@Transactional(rollbackFor = Exception.class)
public int insertCashierMember(CashierMember cashierMember)
{
    try {
        cashierMember.setCreateTime(DateUtils.getNowDate());
        cashierMember.setCreateBy(ShiroUtils.getLoginName());
        SMSUtil.sendCreateMemberMessage(cashierMember.getPhonenumber());
        return cashierMemberMapper.insertCashierMember(cashierMember);
    }catch (Exception e){
        System.out.println("Method error:" + e);
        // Implement manual rollback
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
    return 0;
}
Copy the code

P.S. Just as an example, manual rollback statements don’t have to be added to a catch block, we can use them anywhere. Note that we can add manual rollback statements elsewhere, but the code will continue to execute after the manual rollback statement, so it is not recommended to use manual rollback statements in non-catch blocks of code. If you do, consider whether your business logic is buggy.

Spring Boot Transaction rollback Considerations

Here are a few more notes about Spring Boot transaction rollback:

  1. Wants to realize the rollback, first to ensure the Spring Boot opens the transaction (at startup class to add @ EnableTransactionManagement annotation open transaction (Spring Boot is open transaction by default). The second is that the method used to implement the rollback must be public.
  2. Transactional(rollbackFor= exception.class) means that this method automatically rolls back whatever Exception it throws; If not (rollbackFor= exception.class), this represents the default value, which is rolled back only if the method throws a RuntimeException.
  3. Transactional Transactional is typically implemented in the business layer (that is, the interface implementation class) due to the four major features of transactions (atomicity, consistency, isolation, and persistence).
  4. If you put @Transactional(rollbackFor= exception.class) on an interface implementation class, all methods under this class will be Transactional, meaning that all methods will rollback when they fail.

summary

My experience is limited, some places may not be particularly in place, if you think of any questions when reading, welcome to leave a message in the comments section, we will discuss one by one ๐Ÿ™‡

Please take a thumbs up and a follow (โœฟโ—กโ€ฟโ—ก) for this article ~ a crab (โ—’โ—ก’โ—)

If there are mistakes in the article, welcome to comment correction; If you have a better, more unique understanding, you are welcome to leave your valuable ideas in the comments area.

Love what you love, do what you do, listen to your heart and ask nothing