【发布时间】:2019-04-11 07:31:13
【问题描述】:
我们有一个可以读写MySql的方法,该方法可以被多个线程调用。 db 操作如下:
public List<Record> getAndUpdate() {
Task task = taskMapper.selectByPrimaryKey(id);
if (task.getStatus() == 0) {
insertRecords();
task.setStatus(1);
taskMapper.update(task);
}
// some queries and return data
return someRecordMapper.selectByXXX();
}
private void insertRecords() {
// read some files and create someRecords
someRecordMapper.insertBatch(someRecords);
}
该方法读取任务的状态,如果状态为0,则将(该任务的)一堆记录插入Records表,然后将任务的状态设置为1。
我希望这些数据库操作是事务性的和独占的,这意味着当一个线程进入事务时,其他线程试图读取相同的
任务应该阻塞。否则,他们将看到任务状态为 0,并且会多次调用insertRecords(),从而导致重复数据。
@Transactional 注释似乎不会阻止来自其他线程的事务,它只确保在中止的情况下回滚。所以我认为仅凭@Transactional,上述问题是无法避免的。
我用的是MySql和mybatis,我觉得MySql本身可以实现这样的线程间同步,所以我尽量不引入redis lock等额外的组件来做。我想知道我如何在 Spring 中做到这一点?
【问题讨论】:
-
你试过使用同步块吗?
-
@JoseLuis 这是一个分布式系统,锁需要在数据库中。