我有一个表,其中的值如下所示,
现在,我有两个线程正在尝试做同样的事情。它们如下。
我实现了以下内容,以确保两个线程不会同时拾取相同的记录。
但是,我面临以下问题
如果线程-1正在获取一个记录,而它还没有将该记录标记为“Inprogress”,则另一个线程(线程-2)尝试进行同样的操作。线程-2有时首先获取线程-1已经选取的记录,并在线程-1事务解除锁后返回状态为“Inprogress”的相同记录。
除了在获取记录后添加状态值检查之外,我不知道如何解决这个问题,但我认为可能有一个更好的方法。
如果有更好的方法请告诉我。
下面是负责提取要处理的记录的方法的示例代码,
//存储库
class TableRepository implements JpaRepository<Table, Long> {
@Query(value = "select * from table where status not in ('COMPLETE', 'INPROGRESS') limit 1 for update", nativeQuery=true)
Table getOneValidRecord();
}
//服务类别
class TableService {
@Autowired
private TableRepository repository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Table getOneValidRecord() {
Table table = repository.getOneValidRecord();
table.setStatus("INPROGRESS");
return repository.save(table);
}
}
必须使用中间保留状态。在SQL级别:
步骤1.尽量保留。
UPDATE table
SET status = 'Thread 1 reserved'
WHERE status = 'PENDING'
ORDER BY id
LIMIT 1
第二步。检查预订是否成功。
SELECT COUNT(*)
FROM table
WHERE status = 'Thread 1 reserved'
如果输出为零,则线程2过度保留了同一行。转到步骤1。如果输出超过1,则发生紧急情况。呼叫接线员。
步骤3.处理行。
UPDATE table
SET status = 'INPROGRESS'
WHERE status = 'Thread 1 reserved'
ORDER BY id
LIMIT 1