【发布时间】:2019-06-16 12:50:57
【问题描述】:
我想在数据库中创建一个用户,并使用 AWS SES 向这个案例的用户发送电子邮件。
- 如果用户在数据库中提交事务成功 => 发送电子邮件
- 如果发送电子邮件 AWS SES 失败(检查异常)=> 在数据库中回滚用户创建
- 如果用户在数据库中提交事务失败 => 不要使用 AWS 向用户发送电子邮件
我的代码有问题:如果我的 sendEmail 方法抛出异常,则提交事务。
配置:使用 spring-data-jpa 的 Spring-Boot 项目
class EmailServiceImpl {
@Transactional(rollbackFor = Exception.class)
@Override
public User createUserAndSendEmail(UserDto userDto) throws UserEmailException {
try {
//rollback userCreation if sendEmail throw a checkedException
User user = userService.create(userDto);
sendEmail(user);
return user;
} catch (Exception exception) {
throw new UserEmailException(exception.getMessage());
}
}
//don't send email if userCommit in database failed
private void sendEmail(User user) {
amazonEmailService.sendMail(user);
}
}
class UserServiceImpl {
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public User create(UserDto userDto) throws Exception {
User user = mapp(userDto);
return userRepository.save(user);
}
}
【问题讨论】:
-
您的用户创建是在一个新事务中完成的,因为它具有传播级别
REQUIRES_NEW。所以它会在邮件发送之前提交到数据库中。如果发送邮件失败,它仍然会被提交,因为它是一个单独的事务。要么把所有事情都变成一个单一的交易,要么在发送电子邮件失败时采取补偿措施。
标签: java spring spring-data-jpa spring-transactions