You've already forked FrameTour-BE
feat(printer): 实现任务状态的原子性更新与同步锁机制
- 添加 compareAndSetTaskStatus 方法以支持基于期望状态的任务更新 - 引入 ReentrantLock 实现任务同步处理,防止并发冲突 - 在 XML 映射文件中定义 compareAndSetTaskStatus 的 SQL 更新语句 - 定义任务状态常量:TASK_STATUS_PENDING 和 TASK_STATUS_PROCESSING - 优化任务获取逻辑,确保任务状态在处理前正确更新为 PROCESSING
This commit is contained in:
@@ -28,6 +28,10 @@ public interface PrinterMapper {
|
||||
|
||||
int updateTaskStatus(@Param("id") Integer id, @Param("status") Integer status);
|
||||
|
||||
int compareAndSetTaskStatus(@Param("id") Integer id,
|
||||
@Param("expectStatus") Integer expectStatus,
|
||||
@Param("newStatus") Integer newStatus);
|
||||
|
||||
PrintTaskEntity getTaskById(Integer id);
|
||||
|
||||
List<PrinterResp> listByScenicId(@Param("scenicId") Long scenicId);
|
||||
|
||||
@@ -69,6 +69,8 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@@ -151,12 +153,27 @@ public class PrinterServiceImpl implements PrinterService {
|
||||
printer.setPrinters(printersStr);
|
||||
printerMapper.update(printer);
|
||||
}
|
||||
syncTaskLock.lock();
|
||||
try {
|
||||
while (true) {
|
||||
PrintTaskResp task = printerMapper.findTaskByPrinterId(printer.getId());
|
||||
if (task == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
int updatedRows = printerMapper.compareAndSetTaskStatus(
|
||||
task.getId(),
|
||||
TASK_STATUS_PENDING,
|
||||
TASK_STATUS_PROCESSING
|
||||
);
|
||||
if (updatedRows == 1) {
|
||||
task.setStatus(TASK_STATUS_PROCESSING);
|
||||
return Collections.singletonList(task);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
syncTaskLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void taskSuccess(Integer taskId, WorkerAuthReqVo req) {
|
||||
@@ -427,6 +444,9 @@ public class PrinterServiceImpl implements PrinterService {
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
private static final String USER_PHOTO_LIST_TO_PRINTER = "USER_PHOTO_LIST_TO_PRINTER:";
|
||||
private static final int TASK_STATUS_PENDING = 0;
|
||||
private static final int TASK_STATUS_PROCESSING = 3;
|
||||
private final Lock syncTaskLock = new ReentrantLock();
|
||||
|
||||
@Override
|
||||
public void setUserIsBuyItem(Long memberId, Long id, Long orderId) {
|
||||
|
||||
@@ -152,6 +152,11 @@
|
||||
<update id="updateTaskStatus">
|
||||
UPDATE print_task SET status = #{status}, update_time = NOW() WHERE id = #{id}
|
||||
</update>
|
||||
<update id="compareAndSetTaskStatus">
|
||||
UPDATE print_task
|
||||
SET status = #{newStatus}, update_time = NOW()
|
||||
WHERE id = #{id} AND status = #{expectStatus}
|
||||
</update>
|
||||
<update id="setPhotoCropped">
|
||||
UPDATE member_print SET crop_url = #{url}, update_time = NOW(), print_url = null WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
Reference in New Issue
Block a user