предисловие
Когда мы разрабатываем систему, мы часто сталкиваемся с некоторыми требованиями к транзакциям.Большинство процессов транзакций громоздки (включая изменение запасов, изменение балансов, запись счетов за транзакции и т. д.), поэтому мы должны учитывать потенциал. например, мы модифицируем инвентарь (inventory-1) во время транзакции, а затем нам нужно выполнить платежную операцию, но в это время система внезапно выходит из строя или сеть внезапно прерывается, что делает нас неспособными завершить всю транзакцию процесса, хотя пользователь еще не оплатил, но наш инвентарь уменьшился (продавец должен быть недоволен 👿), поэтому нам нужно использовать откат транзакции для решения вышеуказанной проблемы.
Откат транзакции Spring Boot
У нас есть два способа добиться отката транзакции, первый — автоматический откат, второй — ручной откат, эти две реализации похожи, обе должны использовать аннотацию @Transactional для отката транзакции, следующее непосредственно в коде, посмотрите, что такое разница между ними.
В классе реализации интерфейса есть метод для вставки информации об участниках, давайте трансформируем этот метод и реализуем автоматический откат и ручной откат соответственно👇
/**
* 插入会员信息
*
* @param cashierMember 会员信息
* @return 结果
*/
@Override
public int insertCashierMember(CashierMember cashierMember)
{
cashierMember.setCreateTime(DateUtils.getNowDate());
cashierMember.setCreateBy(ShiroUtils.getLoginName());
SMSUtil.sendCreateMemberMessage(cashierMember.getPhonenumber());
return cashierMemberMapper.insertCashierMember(cashierMember);
}
автоматический откат
/**
* 插入会员信息
*
* @param cashierMember 会员信息
* @return 结果
*/
@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);
}
Мы видим, что к методу добавлена аннотация @Transactional(rollbackFor = Exception.class), через которую можно перехватить исключение, а при возникновении исключения откатить его, тем самым отменив эту складскую операцию.
Во многих методах для обработки исключений используется try-catch.Если в это время в catch обрабатываются возможные исключения, но вручную не выбрасываются исключения (throw), то Spring будет считать метод успешно выполненным, а также не будет откат👇.Правильное решение выглядит следующим образом:
/**
* 插入会员信息
*
* @param cashierMember 会员信息
* @return 结果
*/
@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("方法出现异常:" + e);
//手动抛出异常
throw new RuntimeException();
}
}
P.S. Если оператор try-catch возвращается в блоке операторов finally, исключение, созданное вручную в блоке операторов catch, также будет перезаписано и не будет автоматически откатываться.
Откат вручную
Реализация ручного отката тоже очень проста, достаточно добавить строчку кода для достижения👇
/**
* 插入会员信息
*
* @param cashierMember 会员信息
* @return 结果
*/
@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("方法出现异常:" + e);
//实现手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return 0;
}
P.S. это просто пример, не нужно вручную добавлять инструкцию отката в блоке catch, мы можем использовать инструкцию ручного отката в любом месте.Следует отметить, что, хотя мы можем добавлять операторы ручного отката в других местах, код после оператора ручного отката будет продолжать выполняться, поэтому не рекомендуется использовать операторы ручного отката в блоках кода без перехвата.Если вы должны использовать его так, вы должны тщательно рассмотреть вопрос о том, будет ли ваша бизнес-логика ошибка.
Рекомендации по откату транзакций Spring Boot
Здесь мы кратко скажем несколько замечаний об откате транзакций Spring Boot:
- Чтобы реализовать откат, во-первых, убедитесь, что Spring Boot разрешает транзакции (добавьте аннотацию @EnableTransactionManagement в класс запуска, чтобы включить транзакции (на самом деле Spring Boot разрешает транзакции по умолчанию), а во-вторых, метод реализации отката должен быть общедоступным.
- @Transactional(rollbackFor=Exception.class) означает, что метод будет автоматически откатываться независимо от того, какое исключение было выброшено; если (rollbackFor=Exception.class) не добавлено, оно представляет значение по умолчанию, то есть только тогда, когда метод выбрасывает исключение. Откат происходит только при возникновении непроверенного исключения (RuntimeException).
- Из-за четырех характеристик транзакций (атомарность, согласованность, изоляция и постоянство) @Transactional обычно добавляется к бизнес-уровню (то есть к классу реализации интерфейса).
- Если @Transactional(rollbackFor=Exception.class) добавить в класс реализации интерфейса, то все методы этого класса будут добавлены с управлением транзакциями, то есть все методы будут откатываться при возникновении их собственного исключения.
резюме
Мой опыт ограничен, и некоторые места могут быть не особо к месту.Если у вас возникнут какие-либо вопросы во время чтения, пожалуйста, оставьте сообщение в области комментариев, и мы обсудим их по одному в будущем🙇
Я надеюсь, что вы можете использовать свои милые маленькие руки, чтобы поставить лайк + подписаться (✿◡‿◡), чтобы больше друзей могли увидеть эту статью~ Crab Crab Yo (●'◡'●)
Если в статье есть какая-либо ошибка, пожалуйста, оставьте сообщение, чтобы исправить ее; если у вас есть лучшее и более уникальное понимание, вы можете оставить свои ценные идеи в области сообщений.
Люби то, что любишь, делай то, что делаешь, слушай свое сердце, ничего не проси