Transaction与EventListener
Less than 1 minute
Spring事务与ApplicationEventPublisher
@Transactional
public void handle() {
var account = Account.builder()
.username("huhx")
.password("pass")
.build();
accountRepository.save(account);
publisher.publishEvent(new AccountEvent("huhx"));
var account2 = Account.builder()
.username("huhx2")
.password("pass2")
.build();
accountRepository.save(account2);
}
@Component
@RequiredArgsConstructor
public class AccountEventHandler {
private final BookService bookService;
@EventListener(AccountEvent.class)
public void onAccountEvent(AccountEvent event) {
bookService.save(new BookRequest(event.username()));
throw new RuntimeException();
}
}
// 1. No books saved, no account saved
// 2. add @Transactional on onAccountEvent, No books saved, no account saved
// 3. add @Async on onAccountEvent, two accounts saved, one book saved
// 4. add @Async and @Transactional on onAccountEvent, only two accounts saved
// 5. execute in Thread and with @Transactional, two accounts saved, one book saved(这里加不加@Transactional,没区别)
@Transactional
@EventListener(AccountEvent.class)
public void handle(AccountEvent event) {
new Thread(() -> {
bookService.save(new BookRequest(event.username()));
throw new RuntimeException();
}).start();
}
// 6. change the eventHandle code as following, no accounts saved, only one book saved(这里加不加@Transactional,没区别)
@Transactional
@EventListener(AccountEvent.class)
public void handle(AccountEvent event) {
new Thread(() -> bookService.save(new BookRequest(event.username()))).start();
bookService.save(new BookRequest(event.username()));
throw new RuntimeException();
}
默认情况下,ApplicationEventPublisher的publishEvent方法是同步的