Idempotente Code-Implementierung der allgemeinen JAVA-Schnittstelle

Schnittstellen-Idempotenz

Mehrere Anfragen desselben Benutzers haben die gleichen Auswirkungen auf die Ergebnisse wie eine einzige Anfrage, was als Idempotenz bezeichnet wird

Lösung: Erstellen Sie eine Anti-Heavy-Tabelle

CREATE TABLE `anti_repeat` (
  `id` int(11) NOT NULL,
  `msg` varchar(255) DEFAULT NULL COMMENT '描述信息',
  `create_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Erstellen Sie einen Benutzertabellen-Mock

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `userName` varchar(255) DEFAULT NULL COMMENT '用户名',
  `money` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
dao
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yujie.model.AntiRepeat;

public interface AntiRepeatDao  extends BaseMapper<AntiRepeat> {
}

----------------------------------------------------------------
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yujie.model.User;

public interface UserDao extends BaseMapper<User>{
}
Modell
import com.baomidou.mybatisplus.annotation.TableName;

import java.util.Date;

@TableName(value="anti_repeat")
public class AntiRepeat {
    private Integer id;
    private String msg;
    private Date createDate;

    public AntiRepeat(Integer id, String msg) {
        this.id = id;
        this.msg = msg;
    }

    public AntiRepeat(Integer id, String msg, Date createDate) {
        this.id = id;
        this.msg = msg;
        this.createDate = createDate;
    }
get...
set...
}
--------------------------------------------------------------------
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;

@TableName(value = "t_user")
public class User implements Serializable {
    private static final long serialVersionUID = -2929599080614903612L;

    private Integer id;
    private String username;
    private Integer money;
get...
set...
}
Regler
@RestController
@RequestMapping("/thread")
public class ThreadController {

    @Autowired
    private UserService userService;

    @RequestMapping("/subtraction")
    public  JsonResult subtraction(String username,int money, int id){
        JsonResult jsonResult= new JsonResult();
       try {
            jsonResult = userService.subtraction(username, money, id);
        }catch (Exception e){
            System.out.println("请勿重复提交 ms:"+new Date().getTime());
            jsonResult.setMsg("请勿重复提交");
            jsonResult.setCode(500);
        }
        return jsonResult;
    }

}

Service

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    private UserDao userDao;
    @Autowired
    private AntiRepeatDao antiRepeatDao;


    @Transactional
    @Override
    public JsonResult subtraction(String username, int money, int id) {
        AntiRepeat antiRepeat = antiRepeatDao.selectById(id);
        if(antiRepeat != null){
           throw new RuntimeException("请勿重复提交");
        }

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper();
        lqw.eq(User::getUsername,username);
        User user = userDao.selectOne(lqw);
        user.setMoney(user.getMoney()-money);
        int count = userDao.updateById(user);

        JsonResult jsonResult = new JsonResult();
        String str="用户:"+username+"扣减"+money+"金额";
        if(count == 0){
            jsonResult.setMsg(str+"失败");
            jsonResult.setCode(500);
            return jsonResult;
        }
        AntiRepeat antiRepeat1 = new AntiRepeat(id,str+"成功",new Date());
        antiRepeatDao.insert(antiRepeat1);
        System.out.println(str+"成功 ms:"+new Date().getTime());
        return jsonResult;
    }
}

Testlink http://localhost:8080/thread/subtraction?username=a&money=10&id=1 0086

Gleichzeitiger 100-Thread-Test mit JMeter

用户:a扣减10金额成功 ms:1675186191711
请勿重复提交 ms:1675186191717
请勿重复提交 ms:1675186191719
请勿重复提交 ms:1675186191721
请勿重复提交 ms:1675186191723
请勿重复提交 ms:1675186191725
请勿重复提交 ms:1675186191726
请勿重复提交 ms:1675186191728
请勿重复提交 ms:1675186191729
请勿重复提交 ms:1675186191733

In der Benutzertabelle können Sie sehen, dass Benutzer a erfolgreich von den ursprünglichen 100 Yuan auf 90 Yuan reduziert hat

d8bea07758ed48f4bf212023247dc514.png

                         ​​​​​​​​​​​​​​​​​​ In der Anti-Heavy-Tabelle können Sie sehen, dass es einen zusätzlichen Datensatz mit der ID 10086 gibt

7cf057b237e14be8a022e72133497661.png

 

总结以上就是保证了接口幂等性,流程:携带用户名和金额以及随机的id发送给后端,
后端防重表进行存储随机id,这个id的生成方式很重要,
同一个页面多次点击前端生成同一个id,只有服务器返回结果后才能改变id,
否则当前页面的id永不变

 

Der Nachteil besteht darin, dass der Server nicht auf den Benutzer geantwortet hat, wenn der Benutzer auf die Schaltfläche zum Aufladen klickt. Der Benutzer schließt die Seite und der alte ID-Wert wird zu diesem Zeitpunkt gespeichert. Wenn der Benutzer das nächste Mal den Browser zum Aufladen öffnet, wird er dies tun Finden Sie eine Erinnerung zum erneuten Senden. Zu diesem Zeitpunkt sollte die Rückkehr zum Status der wiederholten Übermittlung umgeleitet werden. Gehen Sie zur ersten Seite, um die ID zu aktualisieren, damit der Benutzer einmal auf die Schaltfläche zum Aufladen klicken kann. Wir sollten dasselbe tun. Zurück zum Wiederholte Übermittlungsaufforderung und Weiterleitung zur Startseite. Wenn der Benutzer das zweite Mal aufladen möchte, muss er einmal auf die Aufladeschaltfläche klicken. Die zweite Methode kann den Browser öffnen. Zufällige ID kann auch gelöst werden, wenn

Supongo que te gusta

Origin blog.csdn.net/qq_42058998/article/details/128825877
Recomendado
Clasificación