分布式架构系统中分布锁的实现

在分布式系统中 存在大量机器集群 外部请求到本系统,负载均衡到各个机器处理 如何保证多台机器处理数据的一致性 是重点需要考虑的问题。

案例:外部系统通过消息队列的方式同步外围数据到本系统 一次性可能发送多条数据,分摊到本系统多台机器处理

场景: 一个商品对应多条供应商数据,存入数据库后插入redis缓存 缓存的key值为商品,value值是供应商的JsonList string。外围过来两条数据,分别分摊到了两台机器处理,每个机器按照

            开启数据库事务--->插入数据--->补偿缓存-->事务提交 逻辑处理

在并发的情况下可能出现 同时进入数据库事务 各自插入数据后 由于事务的隔离型 在未提交是无法看到另一个事务插入的数据的 所以各自查询插入缓存 最终缓存里面供应商只有一条记录

数据库模拟(mysql+dbvisual)

1. 建立实验表

 create table cmmdty_supplier (
     id int auto_increment primary key,
     cmmdty_code varchar(100),--商品编码
     supplier_code varchar(100) --供应商编码
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 2. 打开dbvisual一个窗口 向表中插入商品0001的A供应商数据

set autocommit=0;  --手工控制事务提交
insert into cmmdty_supplier(cmmdty_code,supplier_code)
 values ('0001','A');

    再打开另一个dbvisual窗口 向表中插入商品0001的B供应商数据

 set autocommit=0;

 insert into cmmdty_supplier(cmmdty_code,supplier_code)
 values ('0001','B');

在各自窗口查询表中数据 只能看到各自插入的数据,各自commit后方可看到。

解决方案1:

使用selelct for update 的方式锁住需要处理的数据 经过试验发现只能锁住已有的数据 即更新或者删除表数据,无法锁住新增的数据

解决方案2:

由于redis基于单线程 且setnx命令实现如果value不存在才能设置成功,因此使用redis的setnx功能实现分布锁的功能,具体实现流程




 
 

猜你喜欢

转载自wodeguozili.iteye.com/blog/2379765