package com.cyksj.security; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.model.request.UserBalanceReq; import lombok.RequiredArgsConstructor; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.Map; @Service @RequiredArgsConstructor public class BalanceIdempotency { private final JdbcTemplate jdbc; @Transactional(propagation=Propagation.MANDATORY) public boolean begin(long adminId, String operation, String requestId, UserBalanceReq request) { if(requestId==null || !requestId.matches("[a-zA-Z0-9-]{16,64}")) throw BusinessRuntimeException.getInstance("缺少有效的幂等请求编号,请刷新管理后台"); String payload=request.getUserId()+"\n"+request.getDeductBalance().stripTrailingZeros().toPlainString()+"\n"+request.getRemark(); jdbc.update("INSERT INTO admin_balance_request (admin_id, operation, request_id, payload, completed) VALUES (?, ?, ?, ?, 0) ON DUPLICATE KEY UPDATE request_id=VALUES(request_id)",adminId,operation,requestId,payload); Map row=jdbc.queryForMap("SELECT payload, completed FROM admin_balance_request WHERE admin_id=? AND operation=? AND request_id=? FOR UPDATE",adminId,operation,requestId); if(!payload.equals(row.get("payload"))) throw BusinessRuntimeException.getInstance("请求编号已用于其他金额或用户,请勿修改后重用"); return !Boolean.TRUE.equals(row.get("completed")) && !"1".equals(String.valueOf(row.get("completed"))); } @Transactional(propagation=Propagation.MANDATORY) public void complete(long adminId,String operation,String requestId) { jdbc.update("UPDATE admin_balance_request SET completed=1 WHERE admin_id=? AND operation=? AND request_id=?",adminId,operation,requestId); } }