【发布时间】:2019-04-09 16:49:26
【问题描述】:
我有以下使用 Spring 用 Java 编写的 Web 服务,我用 @Transactional 注释将它包装起来,以确保我们可以在需要时回滚。
它工作正常,除了服务被调用两次的情况,第二次调用发生在第一次调用完成之前。
在这种情况下,由于第一个事务仍在运行并且尚未提交到 DB,第二个事务将通过 full 方法,插入重复行,再次更新状态,并调用 sendAlert()。
这是伪代码。
@Transactional
public ServiceResponse update(ServiceRequest serviceRequest) {
....
if (myDao.getStatus() == "COMPLETE") {
return serviceError;
}
myDao.insertRow();
myDao.updateStatus("COMPLETE");
sendAlert();
}
如何防止第二笔交易在第一笔交易之前完成?将隔离级别设置为未提交读不是一个选项,因为数据库不支持它。
【问题讨论】:
-
你需要做的是同步你的函数,所以第一个调用的执行会阻塞第二个调用的执行。虽然,这完全没有效率。也许你需要做的是防止函数被调用两次。
-
根据您使用的数据库和技术,可以使用数据库锁,以便您拥有单一访问权限。如果您使用诸如休眠之类的东西,请使用乐观锁定来防止这种情况。此外,您可能希望添加一些唯一索引,以防止插入重复项(作为最后的手段)。
-
M. Deinum - 迁移到 Hibernate 不是一种选择,因此唯一可用的解决方案是在数据库上添加约束,因此您的答案最接近解决方案。
标签: java spring transactional