BalanceIdempotency.java 1.9 KB

123456789101112131415161718192021222324252627
  1. package com.cyksj.security;
  2. import com.cyksj.common.exception.BusinessRuntimeException;
  3. import com.cyksj.model.request.UserBalanceReq;
  4. import lombok.RequiredArgsConstructor;
  5. import org.springframework.jdbc.core.JdbcTemplate;
  6. import org.springframework.stereotype.Service;
  7. import org.springframework.transaction.annotation.Propagation;
  8. import org.springframework.transaction.annotation.Transactional;
  9. import java.util.Map;
  10. @Service
  11. @RequiredArgsConstructor
  12. public class BalanceIdempotency {
  13. private final JdbcTemplate jdbc;
  14. @Transactional(propagation=Propagation.MANDATORY)
  15. public boolean begin(long adminId, String operation, String requestId, UserBalanceReq request) {
  16. if(requestId==null || !requestId.matches("[a-zA-Z0-9-]{16,64}")) throw BusinessRuntimeException.getInstance("缺少有效的幂等请求编号,请刷新管理后台");
  17. String payload=request.getUserId()+"\n"+request.getDeductBalance().stripTrailingZeros().toPlainString()+"\n"+request.getRemark();
  18. 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);
  19. Map<String,Object> row=jdbc.queryForMap("SELECT payload, completed FROM admin_balance_request WHERE admin_id=? AND operation=? AND request_id=? FOR UPDATE",adminId,operation,requestId);
  20. if(!payload.equals(row.get("payload"))) throw BusinessRuntimeException.getInstance("请求编号已用于其他金额或用户,请勿修改后重用");
  21. return !Boolean.TRUE.equals(row.get("completed")) && !"1".equals(String.valueOf(row.get("completed")));
  22. }
  23. @Transactional(propagation=Propagation.MANDATORY)
  24. public void complete(long adminId,String operation,String requestId) {
  25. jdbc.update("UPDATE admin_balance_request SET completed=1 WHERE admin_id=? AND operation=? AND request_id=?",adminId,operation,requestId);
  26. }
  27. }