具有@Async的嵌套@Transactional方法
我正在使用Spring和JPA。我已经打开了。在我的用户注册服务方法中,我调用了其他一些带注释的服务方法。这些方法可以执行各种操作,例如发送欢迎电子邮件以及使用我们的第三方支付系统注册新用户。@EnableAsync
@EnableTransactionManagement
@Async
一切正常,直到我想验证第三方支付系统是否成功创建了用户。此时,该方法尝试创建一个(引用新铸造的)并错误@Async
UserAccount
User
javax.persistence.EntityNotFoundException: Unable to find com.dk.st.model.User with id 2017
寄存器调用如下所示:
private User registerUser(User newUser, Boolean waitForAccount) {
String username = newUser.getUsername();
String email = newUser.getEmail();
// ... Verify the user doesn't already exist
// I have tried all manner of flushing and committing right here, nothing works
newUser = userDAO.merge(newUser);
// Here is where we register the new user with the payment system.
// The User we just merged is not /actually/ in the DB
Future<Customer> newCustomer = paymentService.initializeForNewUser(newUser);
// Here is where I occasionally (in test methods) pause this thread to wait
// for the successful account creation.
if (waitForAccount) {
try {
newCustomer.get();
} catch (Exception e) {
logger.error("Exception while creating user account!", e);
}
}
// Do some other things that may or may not be @Aysnc
return newUser;
}
支付服务呼唤完成注册用户的工作,如下所示:
@Async
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Future<Customer> initializeForNewUser(User newUser) {
// ... Set up customerParams
Customer newCustomer = null;
try {
newCustomer = Customer.create(customerParams);
UserAccount newAccount = new UserAccount();
newAccount.setUser(newUser);
newAccount.setCustomerId(newCustomer.getId());
newAccount.setStatus(AccountStatus.PRE_TRIAL);
// When merging, JPA cannot find the newUser object in the DB and complains
userAccountDAO.merge(newAccount);
} catch (Exception e) {
logger.error("Error while creating UserAccount!", e);
throw e;
}
return new AsyncResult<Customer>(newCustomer);
}
这里列出的StackOverflow答案建议我设置一个传播,我已经这样做了,但没有这样的运气。REQUIRES_NEW
任何人都可以为我指出正确的方向吗?我真的不想直接从我的控制器方法调用支付服务。我觉得这肯定是一个服务水平要求。
感谢您的任何帮助!