我有一个 Spring 应用程序,它使用以下命令更新 MySQL DB 中的特定实体详细信息@Transactional
方法,并且在同一方法中,我尝试使用调用另一个端点@Async
这是另一个 Spring 应用程序,它从 MySql DB 读取相同的实体并更新 redis 存储中的值。
现在的问题是,每次我更新实体的某些值时,有时它会在 Redis 中更新,有时则不会。
当我尝试调试时,我发现有时第二个应用程序从 MySql 读取实体时会选择旧值而不是更新后的值。
谁能建议我可以采取什么措施来避免这种情况,并确保第二个应用程序始终从 Mysql 中选择该实体的更新值?
M. Deinum 的答案很好,但还有另一种方法可以实现此目的,这对于您的情况可能更简单,具体取决于您当前应用程序的状态。
您可以简单地将对异步方法的调用包装在一个事件中,该事件将在当前事务提交后进行处理,这样您每次都可以从数据库中正确读取更新的实体。
做到这一点非常简单,让我向您展示:
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
@Transactional
public void doSomething() {
// application code here
// this code will still execute async - but only after the
// outer transaction that surrounds this lambda is completed.
executeAfterTransactionCommits(() -> theOtherServiceWithAsyncMethod.doIt());
// more business logic here in the same transaction
}
private void executeAfterTransactionCommits(Runnable task) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
public void afterCommit() {
task.run();
}
});
}
基本上,这里发生的是,我们为当前事务回调提供一个实现,并且我们只重写 afterCommit 方法 - 还有其他方法可能有用,请检查它们。如果您想在其他部分使用此代码或只是使该方法更具可读性,为了避免键入相同的样板代码,我在辅助方法中提取了该代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)