Introduction to the usage of Java idempotent solution

Idempotence means that one and multiple requests for a resource have the same impact on the resource status. In Java development, realizing the idempotence of interfaces is an important means to improve service quality. Below we elaborate on Java idempotence solutions from multiple aspects such as database locks, Token mechanism, pessimistic locking and optimistic locking.

1. Database lock

1. In database operations, the lock mechanism of the database itself (such as MySql's row lock and table lock) can be used to ensure the idempotence of the interface.

2. When using locks, you need to pay attention to the granularity and holding time of the lock to reduce performance problems caused by locks.

public void insertOrder(Order order){
    synchronized(this){
        if(orderDao.selectById(order.getId())!=null){
            throw new RuntimeException("order exists");
        }else{
            orderDao.insert(order);
        }
    }
}

2. Token mechanism

1. The idempotence of the interface can also be achieved using the Token mechanism. The specific implementation method is: when the interface is requested for the first time, a Token is generated, the Token is saved on the server side, and returned to the client. When the client requests the interface for the second time and thereafter, it needs to bring this Token. The server uses the Token to determine whether to repeat the request.

2. When using the Token mechanism, you need to pay attention to the life cycle management of Token and how to deal with the problem of Token loss.

public String getToken(){
    String token = UUID.randomUUID().toString();
    tokenMap.put(token, true);
    return token;
}

public void checkToken(String token){
    Boolean exist = tokenMap.get(token);
    if(exist==null||!exist){
        throw new RuntimeException("request replay or token not exists");
    }else{
        tokenMap.remove(token);
    }
}

3. Pessimistic locking and optimistic locking

1. In a concurrent environment, we can also use pessimistic locking and optimistic locking to ensure the idempotence of the interface. Pessimistic locking assumes the worst case scenario. Every time you get data, you think that other threads will modify the data. Therefore, you will lock every time you get data to ensure that the data will not be modified by other threads during the lock period.

2. Optimistic locking is the opposite. It assumes the best situation. Every time it gets data, it thinks that other threads will not modify the data, so it will not lock. However, when submitting the update, it will judge whether there is any data during this period. Other threads modified this data.

//悲观锁
public void getPessimisticLock(){
    synchronized(this){
        legacyService.perform();
    }
}

//乐观锁
public void getOptimisticLock(){
    int oldValue = legacyService.getValue();
    doSomething();
    int newValue = legacyService.getValue();
    if(oldValue != newValue){
        throw new RuntimeException("value has been modified by others");
    }else{
        legacyService.commit();
    }
}

Guess you like

Origin blog.csdn.net/linyichao123/article/details/133536477