多线程现场事故解决案例

1.最近做一个项目,需要有分配授权数量,但初始化必须是0
2.授权的数量在使用中必须一个个扣除
3.每次消耗都要进行记录,然后再扣减数量

看起来上面三部都没问题,
问题就在第三步呀,消耗记录报错后,数量没有来得及扣除,这样相当与白送了一键给对方,为什么呢
,因为你是用了就要扣除,我管你报不报错,不够你就在买。

举个例子,你买两个包子,老板把俩包子给你了,你吃一个,然后想再吃一个,啪,掉地上了,这时候你再付钱说只给你一个包子的钱,地上那个我没吃,你看老板抽不抽你就完事了。
下面进入正题!!!!

 

package com.wangbiao.sqilte.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wangbiao.sqilte.entity.Student;
import com.wangbiao.sqilte.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * (Student)表控制层
 *
 * @author makejava
 * @since 2023-03-26 21:33:55
 */
@Slf4j
@RestController
@RequestMapping
public class StudentController {
    /**
     * 服务对象
     */
    private static ReentrantLock object = new ReentrantLock();
    static ExecutorService executorService = new ThreadPoolExecutor(5, 10, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));
    private final StudentService studentService;

    public StudentController(StudentService studentService) {
        this.studentService = studentService;
    }

    /**
     * @return 查询结果
     */
    @GetMapping("/test")
    public Object queryByPage() {
        //从0开始
        AtomicInteger integer = new AtomicInteger(0);

        for (int i = 1; i <= 50; i++) {
            Thread runnable = new Thread() {
                @Override
                public void run() {
                    try {
                        object.lock();
                        integer.getAndAdd(1);
                       int b= integer.get();
                        System.out.println("2222222222222222:" + b);
                        //让等于50抛出异常
                        if(b==50){
                            int c=b/0;
                        }
                        //问题就在b==50,这式上面是50,下面才49
                        AtomicInteger atomicInteger = new AtomicInteger(getAdd());
                        atomicInteger.getAndAdd(1);
                        int i1 = atomicInteger.get();
                        System.out.println("11111111111:" + i1);
                        //每次拿出来叠加后更新
                        update(i1);
                    }catch (Exception e){
                        log.error("错啦!!!!");
                    }finally {
                        object.unlock();
                    }
                }
            };
            executorService.submit(runnable);
        }
        return null;
    }

    public int getAdd() {
        //在数据库里面,这里一开始也是返回0
        Student student = studentService.getOne(new LambdaQueryWrapper<Student>().eq(Student::getId, 1));
        return student.getAge();
    }

    public void update(int a) {
        studentService.update(null, new LambdaUpdateWrapper<Student>().set(Student::getAge, a).eq(Student::getId, 1));

    }
}

 

 

优化后代码

 

package com.wangbiao.sqilte.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wangbiao.sqilte.entity.Student;
import com.wangbiao.sqilte.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * (Student)表控制层
 *
 * @author makejava
 * @since 2023-03-26 21:33:55
 */
@Slf4j
@RestController
@RequestMapping
public class StudentController {
    /**
     * 服务对象
     */
    private static ReentrantLock object = new ReentrantLock();
    static ExecutorService executorService = new ThreadPoolExecutor(5, 10, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));
    private final StudentService studentService;
    private final TransactionTemplate transactionTemplate;

    public StudentController(StudentService studentService,
                             TransactionTemplate transactionTemplate) {
        this.studentService = studentService;
        this.transactionTemplate = transactionTemplate;
    }

    /**
     * @return 查询结果
     */
    @GetMapping("/test")
    public Object queryByPage() {
        //从0开始
        AtomicInteger integer = new AtomicInteger(0);

        //无返回式编程事务
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                for (int i = 1; i <= 50; i++) {
                    Thread runnable = new Thread() {
                        @Override
                        public void run() {
                            try {
                                object.lock();
                                integer.getAndAdd(1);
                                int b = integer.get();
                                System.out.println("2222222222222222:" + b);
                                //让等于50抛出异常
                                if (b == 50) {
                                    int c = b / 0;
                                }
                                //问题就在b==50,这式上面是50,下面才49
                                AtomicInteger atomicInteger = new AtomicInteger(getAdd());
                                atomicInteger.getAndAdd(1);
                                int i1 = atomicInteger.get();
                                System.out.println("11111111111:" + i1);
                                //每次拿出来叠加后更新
                                update(i1);
                            } catch (Exception e) {
                                //发生异常进行回滚  }}}}}优化点
                                transactionStatus.setRollbackOnly();
                                log.error("错啦!!!!");
                            } finally {
                               
                                object.unlock();
                            }
                        }
                    };
                    executorService.submit(runnable);
                }
                
            }
        });

        return null;
    }

    public int getAdd() {
        //在数据库里面,这里一开始也是返回0
        Student student = studentService.getOne(new LambdaQueryWrapper<Student>().eq(Student::getId, 1));
        return student.getAge();
    }

    public void update(int a) {
        studentService.update(null, new LambdaUpdateWrapper<Student>().set(Student::getAge, a).eq(Student::getId, 1));

    }
}

 

posted @ 2023-03-29 23:54  余生请多指教ANT  阅读(13)  评论(0编辑  收藏  举报