1-2.数据一致性问题

来源:互联网 发布:美容院调整型内衣 知乎 编辑:程序博客网 时间:2024/06/05 19:04
避免并发造成数据不一致的问题,即不希望因为并发操作导致数据不一致或结果不准确。

基本思路就是不让线程同时操作,将并发操作顺序化,方法有:

1.加锁(分布式锁)
当多个线程同时操作时,由于有锁的原因,只有第一个获得锁的线程才能操作,其他线程将按获得锁的顺序进行操作;

2.使用缓存或队列(并发请求串行化)
将所有的线程请求放到队列中,然后从队列中取线程操作。
跟线程阻塞的处理方法一致。
这种方法要求将所有的操作封装到线程中,不是轻量级,不是一种局部处理的方法。

3.乐观锁(秒杀,领券)
先从数据库取数据,比如库存count;
然后update count-1,获得返回结果:
如果结果为1,说明成功;
如果结果为0,再取一次count:
如果count=0说明确实库存为0;
如果count>0,说明刚才由于并发问题导致减库存失败,实际库存并不为0,这种情况下需要循环操作直到update成功或库存为0。

乐观锁扩展:
所有对数量的更新操作,包括增加和减少,都要使用乐观锁:先查数据库再更新;
如果是减少,参考上面;
如果是增加,如果update结果为1,说明成功;
如果为0,循环(取数据,update直到结果为1)

乐观锁:
通过不断重试确定更新是否成功。
循环:
取数据
update
  |----=1成功,跳出循环
  |----=0失败
    |----如果是减少,取数据,=0说明库存为0,跳出循环
    |----如果是增加,取数据,判断是否达到上限,是跳出循环

注意:这种方法不是很可靠,有可能当前线程在update时,已有多个线程进行过更新,这时当前线程可以更新成功,但是覆盖了其他线程的更新。
例如:
A线程准备将count从5减为4,在此更新未完成前,B线程已将count从5减为4,此时A线程的更新将不会成功;
如果在此期间又有线程C将count从4减为3,则线程A可以更新成功,但是将count从3变成4,是一种错误的更新,覆盖了其他线程的结果;
上面两种情况本质上都是数据一致性的问题,
使用循环取值的方法可以解决第一种情况,但不能解决第二种情况;
更好的方法参考乐观锁目录下的方法;
0 0
原创粉丝点击