web开发中多线程问题

SandKing 发布于 2019/12/11 10:52
阅读 1K+
收藏 0

多线程并发数据一致性问题。是一个一直热议的话题。

我一直有一个疑问,是否是普遍的web项目中都存在这样的并发问题,只是并发不高没有暴露出来。

例:web server一般都是直接操作数据库,关系型数据库或者nosql都行

现在有一个管理后台,其中有一条条商品数据

ID 名称 价格 折扣 时间
1 面包 ¥5 0.9 2019-12-11

其中管理员A、管理员B,都查询到这条数据,管理员A修改价格为¥7,管理员B修改价格为¥6,因为webServer是多线程的,这个地方并发修改就会出现数据安全问题!

网上看很多的解决方案:

  1. 加锁方案:这种管理后台如果都是公共数据你如何去加锁?
  2. 逻辑单线程:这种一般是在做游戏开发才会这样去做(所有操作串行)
  3. 每个对象加版本号?

以上疑问球大佬解答一下。之前我们做游戏开发,因为共享数据不多,逻辑单线程、actor、进程内玩家缓存。都能解决此问题。不知道web开发中又是怎么一种处理方式呢

加载中
0
小伯恩
小伯恩

使用事务和锁,数据库也自带这样的机制,一个人完成了才释放事务和锁,在让另一个人来继续

0
独孤晓林

数据库行锁

0
快乐的一只小青蛙
快乐的一只小青蛙

其中管理员A、管理员B,都查询到这条数据,管理员A修改价格为¥7,管理员B修改价格为¥6,因为webServer是多线程的,这个地方并发修改就会出现数据安全问题!

之前我们做游戏开发,因为共享数据不多,逻辑单线程、actor、进程内玩家缓存。

 

恕我看不懂描述, 单线程,缓存这些能解决A和B查询的都是5,然后分别写入6和7的问题?

0
z
zb75154888

行级锁啊 mysql可以select for update

0
f
freezingsky

运营后台, 同时变更同一条记录, 基本使用乐观锁. 

0
为爱痴狂
为爱痴狂

innodb引擎update自带锁,更新条件带索引锁行,否则锁表。使用数据库锁就解决了

自由PHP
自由PHP
回复 @SandKing : 你只要在update的时候多加一个条件就可以了, update table SET field = (case when field>2000 then field-2000 else field end) where id=1 这条语句在then的时候,返回的影响条数是1,而执行else的时候,返回的影响条数为0
z
zb1490491419513
回复 @SandKing : 这就是事务啊
SandKing
SandKing
我能想到的就3个方案 1.逻辑串行 2.数据加版本号 3.读取数据时就加锁(无论修不修改数据),逻辑完毕(释放锁)
SandKing
SandKing
数据库锁?如果是这样的情况。比如有一电信的套餐内有5个号码,他们是共享积分的,当前积分2030分,使用2000分可以兑换10M流量,现在套餐内2个用户并发了兑换逻辑。注意是并发了逻辑。在代码逻辑判断时都2030>2000都成立了?数据库锁能做到数据安全? 只是举例而已不是特例,不限逻辑。可能另一个人使用积分干其他的事情。共享数据也不仅仅是积分,还有很多其他数据,都要保证数据安全。这样锁也没法保证。
0
kakai
kakai
基本超卖问题,搜索一下这类问题有几种解决方案的。一般是数据库表锁行级锁(性能差);每行加版本号的乐观锁(性能稍微好些,但实现稍显繁琐);基于redis的原子操作,实现复杂些但性能很好,不过还得保证redis的稳健性。
0
网瘾少年徐志摩
网瘾少年徐志摩

1,2,3分别对应悲观锁,同步/异步阻塞,乐观锁
redis分布式锁,百度去吧

0
sxgkwei
sxgkwei

我和 @快乐的一只小青蛙 观点一致。一堆的什么锁,什么方案,什么原子性,是不是石乐志?你这明明就是看到数据之后,更新了两次。请问什么奇葩方案,让你第一次更新成功,第二失败;或者反之?如果真有方案让你这种标准更新操作都有一次失败的,那真实奇葩中的战斗机方案了。

0
ifeio
ifeio

没关注这种问题,这种场景倒是遇到过,mysql会自动处理,应该是进行了锁操作的

返回顶部
顶部