web开发中,多个线程对同一数据修改时的线程安全问题

在web应用中,每次请求都是不同的线程,因此,当对统一数据进行访问更新的时候,有可能会引发数据问题。

举个例子:有一个apple表,里面有个字段count,表示某种apple的数量。同时,后台提供获取这种苹果的服务,获取苹果之后,就需要将count的值修改。

假设apple表中有这么一条数据
id      count
12345   100
----------


    class Apple{
        int count;
    }

    public interface AppleMapper{
        @Select("select count from apple")
        Apple getApple();

        @Update("update apple set count = #{count}")
        void updateCount(int count);
    }

    service:
    public void getApple(int num) {
    //step1
    Apple apple = appleMapper.getApple();
    //取走num个苹果后剩下count个苹果,假设num<getCount()
    int count = apple.getCount() - num;
    //step2
    appleMapper.updateCount(count);
    }

现在,有两条请求,都想获得苹果,req1.getApple(5)和req2.getApple(6);如果req1在step2完成后,req2才到达step1,那么数据库结果没有任何问题,但是,一旦req2在req1执行万step2时,就执行了step1,那么此时,req2.getCount() = 100,req1.count = 95,req2.count = 94,此时,无论哪个count存入数据库,都将是错误的,实际的count应该是89。

解决办法:
不要在业务逻辑中计算,然后将计算结果传入数据库,可传入需要改变的值,数据库sql改为”update apple set count = count + #{num}”。
还有种不推荐的方法:以在stept1处获得的值作为条件,如果数据库的值和我在step1处取出的值一致,说明没有人修改这个值,那么就更新,否则不更新。

这样的场景其实也不是很常见,一般前端将最终结果传入,只更新最终结果,就没这种问题了。最后,切记,遇到更新数值的操作时,不要在逻辑里计算,并将结果作为最终值更新,应该交由数据库去处理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值