Java 基于另一个线程结果的数据库回滚
我对我的业务逻辑进行了顺序处理,包括: 将消息发送到远程服务器 将该消息保存到数据库中 Sequential.java 我意识到,如果我同时完成这两项任务,我可以提高绩效。一个线程发送消息,另一个线程将其保存到数据库 Parallel.java 并行方法的问题是,即使发生异常,消息也会保存到数据库中。如果发生异常,但仍并行运行这两个任务,是否有任何方法阻止保存Java 基于另一个线程结果的数据库回滚,java,spring,multithreading,jpa,concurrency,Java,Spring,Multithreading,Jpa,Concurrency,我对我的业务逻辑进行了顺序处理,包括: 将消息发送到远程服务器 将该消息保存到数据库中 Sequential.java 我意识到,如果我同时完成这两项任务,我可以提高绩效。一个线程发送消息,另一个线程将其保存到数据库 Parallel.java 并行方法的问题是,即使发生异常,消息也会保存到数据库中。如果发生异常,但仍并行运行这两个任务,是否有任何方法阻止保存 可能是某种基于触发器的回滚。一旦保存并提交了数据,就无法回滚事务。现在,您可以从另一个线程发送消息,而不是将消息保存到DB的线程。因此,
可能是某种基于触发器的回滚。一旦保存并提交了数据,就无法回滚事务。现在,您可以从另一个线程发送消息,而不是将消息保存到DB的线程。因此,您的消息可能在发送消息之前保存到DB,在这种情况下,如果在发送消息期间出现任何异常,则无法回滚。我建议使用CompletableFuture,如下所示:
CompletableFuture.supplyAsync(() -> {
// send message from here
System.out.println("Msg send");
return msg;
}).exceptionally(ex -> {
// handle the exception
System.out.println("Exception occour");
return "";
}).thenAccept((msgTosave) -> {
if (!msgTosave.isEmpty()) {
// save your msg to db here
System.out.println("Msg To save : " + msgTosave);
}
});
Spring在多线程环境中不支持开箱即用的回滚,但您可以通过编程方式强制执行它。参考
// send: 1st thread
executor.execute(() -> {
try {
sender.send(message);
} catch(SendingException e) {throw SomeException("Couldn't send.", e);}
});
// save: 2nd thread
executor.execute(() -> dbService.save(message));
CompletableFuture.supplyAsync(() -> {
// send message from here
System.out.println("Msg send");
return msg;
}).exceptionally(ex -> {
// handle the exception
System.out.println("Exception occour");
return "";
}).thenAccept((msgTosave) -> {
if (!msgTosave.isEmpty()) {
// save your msg to db here
System.out.println("Msg To save : " + msgTosave);
}
});