数据一致性

在高并发的场景里,如何保证一个业务事务的数据一致性非常重要

在高并发的业务场景中通常出现这样的现象

T1读数据B(sql1)

T2读数据B(sql2)

T1修改数据B(sql3)(数据库会自动对事务加上排他锁)

T2修改数据B(sql4)(数据库会自动对事务加上排他锁)

在这样的场景中通常会出现几种情况:

1、不加锁的条件下,T2修改产生脏数据。或者当T2修改以查询的结果为条件则修改失败(分布式系统容易导致数据不一致)

2、在数据库层面(sql1、sql2)加上共享锁时,通常容易致使sql3无法执行,由于sql1、sql2,都对统一数据加上共享锁,但是在修改时都无法对数据加上排他锁导致业务产生死锁情况,导致程序崩溃

3、对于第二种情况的,解决方案有,在程序业务处理的过程中T1在读取数据的时候手都对数据B加上排他锁,因此程序当业务T2进入处理程序时,也会对数据B加排他锁,但是T1业务还在进行没有是否锁,T2进出便会挂起等待T1的事务进行完成,(但是在分布式的系统中由于一个业务由多服务,多数据库事务组成,无法做到对事物的统一管理)

4、在单机的业务环境下,通常可以通过代码业务层面解决,高并发产生的数据问题。具体解决方案为对可能产生高并发的业务处理代码快加上程序锁,使其在做业务处理的时候,由多线程的业务转化成单线程的业务

 但是这种情况,仅限于再请求量处理及时的情况下才能使用,一旦有大量的请求涌进,由于单线程的业务处理无法及时,系统拥堵量过大导致系统崩溃,

5,鉴于4的解决方案在系统处理效率的牺牲比较大不可取,于是可以采用将单线程业务,使用mq机制将所有的请求统一放入一个一队列中,使其业务在处理的时候通过mq的排队机制进行处理,当mq队列过大的时候,可以在处理mq里面的业务时,通过多线程的业务方式提高系统的效率,但对统一数据操作时需要,保证,该数据不存在正在处理的线程(存在并发风险)

6、使用redis分布式锁,来提高单线程处理效率低下的问题,具体解决方案为。当一个业务处理进来时,程序会对业务处理的主体表数据,获取一个锁,并保存在redis中,(当redis中已存在该数据的锁时,程序会进入一个不断获取锁的机制,直至获取到锁,并获取对数据的操作权限),从而提高系统的处理效率,以及业务数据的一致性

 redis锁实现方式:

JedisPoolConfig 继承Java通用对象池GenericObjectPool

 

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_31854907/article/details/84982713