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 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);
|
PrintTaskEntity getTaskById(Integer id);
|
||||||
|
|
||||||
List<PrinterResp> listByScenicId(@Param("scenicId") Long scenicId);
|
List<PrinterResp> listByScenicId(@Param("scenicId") Long scenicId);
|
||||||
@@ -51,4 +55,4 @@ public interface PrinterMapper {
|
|||||||
void updateUserPhotoListToPrinter(Long memberId, Long scenicId, Integer printerId);
|
void updateUserPhotoListToPrinter(Long memberId, Long scenicId, Integer printerId);
|
||||||
|
|
||||||
List<MemberPrintResp> listRelationByOrderId(Long orderId);
|
List<MemberPrintResp> listRelationByOrderId(Long orderId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -151,11 +153,26 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
printer.setPrinters(printersStr);
|
printer.setPrinters(printersStr);
|
||||||
printerMapper.update(printer);
|
printerMapper.update(printer);
|
||||||
}
|
}
|
||||||
PrintTaskResp task = printerMapper.findTaskByPrinterId(printer.getId());
|
syncTaskLock.lock();
|
||||||
if (task == null) {
|
try {
|
||||||
return Collections.emptyList();
|
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();
|
||||||
}
|
}
|
||||||
return Collections.singletonList(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -427,6 +444,9 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<String, String> redisTemplate;
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
private static final String USER_PHOTO_LIST_TO_PRINTER = "USER_PHOTO_LIST_TO_PRINTER:";
|
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
|
@Override
|
||||||
public void setUserIsBuyItem(Long memberId, Long id, Long orderId) {
|
public void setUserIsBuyItem(Long memberId, Long id, Long orderId) {
|
||||||
@@ -550,4 +570,4 @@ public class PrinterServiceImpl implements PrinterService {
|
|||||||
printTaskMapper.insertTask(task);
|
printTaskMapper.insertTask(task);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,11 @@
|
|||||||
<update id="updateTaskStatus">
|
<update id="updateTaskStatus">
|
||||||
UPDATE print_task SET status = #{status}, update_time = NOW() WHERE id = #{id}
|
UPDATE print_task SET status = #{status}, update_time = NOW() WHERE id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
<update id="compareAndSetTaskStatus">
|
||||||
|
UPDATE print_task
|
||||||
|
SET status = #{newStatus}, update_time = NOW()
|
||||||
|
WHERE id = #{id} AND status = #{expectStatus}
|
||||||
|
</update>
|
||||||
<update id="setPhotoCropped">
|
<update id="setPhotoCropped">
|
||||||
UPDATE member_print SET crop_url = #{url}, update_time = NOW(), print_url = null WHERE id = #{id}
|
UPDATE member_print SET crop_url = #{url}, update_time = NOW(), print_url = null WHERE id = #{id}
|
||||||
</update>
|
</update>
|
||||||
@@ -172,4 +177,4 @@
|
|||||||
<delete id="deleteUserPhoto">
|
<delete id="deleteUserPhoto">
|
||||||
DELETE FROM member_print WHERE member_id = #{memberId} AND scenic_id = #{scenicId} AND id = #{relationId} LIMIT 1;
|
DELETE FROM member_print WHERE member_id = #{memberId} AND scenic_id = #{scenicId} AND id = #{relationId} LIMIT 1;
|
||||||
</delete>
|
</delete>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user