当前位置:网站首页>[redis realizes seckill service ④] one order for one person, and cannot be purchased repeatedly

[redis realizes seckill service ④] one order for one person, and cannot be purchased repeatedly

2022-06-25 00:45:00 Bulst

For seckill fruit , A user can only kill one order of one kind of fruit .

The business process

 Insert picture description here

Concurrency issues

normal
 Insert picture description here
Concurrency issues
 Insert picture description here

Lock to ensure thread safety

Determine if an order exists , To ensure thread safety , We can lock ,synchronized.

 Insert picture description here

If you add it to the method , It's right this Lock , in other words , All users have to lock in , This is not in line with our expectation of "one person, one order" .

We are based on users ID Lock , Reduce the range of locks , Lifting performance .

userId.toString().intern() Ensure that the only 【 Returns the canonical representation of a string object 】

@Transactional
public Result createVoucherOrder(Long voucherId) {
    
    //  One person, one single 【 Among the filters configured above , If the logged in user , Will be in ThreadLocal Add user information 】
    Long userId = UserHolder.getUser().getId();
	
	//  Lock the execution code block ,intern() Methods to avoid waste of resources 
    synchronized (userId.toString().intern()) {
    
        //  Query order 
        int count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();
        //  Judge whether it exists 
        if (count > 0) {
    
            //  The user has already purchased 
            return Result.fail(" The user has purchased once !");
        }

        //  Deducting the inventory 
        boolean success = seckillVoucherService.update()
                .setSql("stock = stock - 1") // set stock = stock - 1
                .eq("voucher_id", voucherId).gt("stock", 0) // where id = ? and stock > 0
                .update();
        if (!success) {
    
            //  Deduction failed 
            return Result.fail(" Insufficient inventory !");
        }

Cluster problem

If you are in a cluster environment , There will be multiple JVM There is , There will be multiple lock monitors , In this way, the lock will be completely invalid , There will still be thread safety problems , therefore , In the next article we will use redis Implement distributed locks to ensure thread safety .

 Insert picture description here

原网站

版权声明
本文为[Bulst]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206242001480459.html