mysql的乐观锁_mysql乐观锁在分布式系统中的解决方案

在分布式环境中,由于用户请求可能被负载均衡到不同实例,传统的JVM锁无法确保数据一致性。针对这个问题,文章介绍了使用MySQL乐观锁来解决电商库存减库存操作可能导致的不一致问题。乐观锁通过在商品表中添加版本号字段,读取数据时包含版本号,在更新时对比版本号,如果一致则更新,否则认为数据已过期,返回错误。示例代码展示了如何使用乐观锁进行库存更新操作。
摘要由CSDN通过智能技术生成

问题背景

在分布式系统中,应用会进行多实例部署,不同势力有各自的JVM,被负载均衡到不同实例上的用户请求通过JVM的锁机制无法互斥。例如,电商购物环节的减库存操作,有可能导致用户同时点击导致库存不一致的问题。

解决方案

使用MySQL乐观锁

分布式锁(暂不介绍)

MySQL乐观锁具体实现

相对于悲观锁,它只有在数据提交的时候进行冲突校验,如果产生数据冲突,返回错误信息,进行相应处理。

在数据库表中添加version版本号字段

CREATE TABLE `goods` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(64) NOT NULL DEFAULT '',

`remaining_number` int(11) NOT NULL,

`version` int(11) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

读取数据包括版本号

数据更新时对这条数据的version + 1

update goods

set `name`=#{name},

remaining_number=#{remainingNumber},

version=version+1

where id=#{id} and version=#{version}

]]>

判断数据库中要更新时的版本号和第一次取到数据的版本号是否一致,一致的话,说明更新,否则认为数据过期,返回错误信息到页面上。

@Override

public Boolean updateGoodCAS(Integer id, Integer decreaseNum) {

Goods good = goodsMapper.selectGoodById(id);

System.out.println(good);

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

}

good.setRemainingNumber(good.getRemainingNumber() - decreaseNum);

int result = goodsMapper.updateGoodCAS(good);

System.out.println(result == 1 ? "success" : "fail");

return result == 1;

}

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值