Arn*_*pps 6 java spring spring-transactions spring-data-jpa
我想在数据库中创建一个用户,并使用 AWS SES 向此案例的用户发送电子邮件。
我的代码存在问题:如果我的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);
}
}
Run Code Online (Sandbox Code Playgroud)
要在 TX commit 后执行某些操作,您可以使用@TransactionalEventListenerwith TransactionPhase.AFTER_COMMIT(默认设置)。将您想要执行的操作放入TransactionalEventListener:
使用ApplicationEventPublisher来发布UserCreatedEvent:
public class EmailServiceImpl {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Transactional(rollbackFor = Exception.class)
public User createUserAndSendEmail(UserDto userDto) throws UserEmailException {
try {
User user = userService.create(userDto);
//Publish UserCreatedEvent such the UserCreatedEventHandler can handled it after TX commit
applicationContext.publishEvent(new UserCreatedEvent(user));
return user;
} catch (Exception exception) {
throw new UserEmailException(exception.getMessage());
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且UserCreatedEvent将在 TX 提交后由该处理程序处理:
@Component
public class UserCreatedEventHandler {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handle(UserCreatedEvent event) {
try{
amazonEmailService.sendMail(user);
System.out.println("Good, can send email.");
}catch(Exception exception){
System.out.println("Sad, fail to send email , so remove user from DB...");
userService.remove();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Deinum 的好接球。如果你使用我的建议,你必须更改userService.create()为@Transactional(propagation = Propagation.REQUIRES)
| 归档时间: |
|
| 查看次数: |
3031 次 |
| 最近记录: |