更新于 2018-12-23 22:21:44
前言:一年前的写的,当时的做法并不能在并发下保证流水号的唯一性,因为当时并没有写多线程测试过...
思路
sCode
sName
sQz
sValue
order
订单
DD
18120100
首先每个业务的流水号对应表中的一条数据
每个要获取流水号的线程调用 一个用来生成流水号的 存储过程
根据sCode 找到 sValue。
if (sValue == null)
初始化值
else
sValue ++
敲黑板!划重点!
分析:上述的思路看似没什么问题,但是如果两个线程并发的执行会出现两个事务读取到相同的数据,同时都执行初始化或者自增。
方案:使用 MySQL 写锁(select...for update,也叫X锁,排它锁) 来解决这一问题
例如:事务A和事务B同时进行,事务A 拿到 当前这条数据的写锁,此时如果事务B 想访问这条数据需要等待事务A结束。并发时让两个事务对同一条数据的操作变成了串行化。
CREATE TABLE `sys_sno` (
`sCode` varchar(50) DEFAULT NULL COMMENT '编码',
`sName` varchar(100) DEFAULT NULL COMMENT '名称',
`sQz` varchar(50) DEFAULT