流水记录方式

有时候会遇到这样的问题。假如我们有一个数据库X中数据数量的上限A,例如优惠流水的次数控制

同时,用户的某些行为会触发数据入库。而在入库前我们需要先进行count(*)的计算,select count(*) from X 。 

如果count(*) >= A,则阻止该用户的数据入库。


问题在于,假如有两个用户m.n同时触发数据入库,而count(*) = A - 1; 那么按上面的算法,m.n的数据均会入库,导致count(*) =  A + 1,出现BUG。当并发高时该现象会更为严重。


解决办法为 set autocommit = 0 ; begin work ; select count(*) from X FOR UPDATE ; insert .....; commit work。开启事务,加入行锁。那么当m先执行该sql时,得到count(*) = A -1.同样需要执行该sql 的n会等待,直到m的事务提交后再执行n的操作,于是当n查询时会得到count(*) = A从而阻止n的入库

事务+行锁,是并发的重要解决办法

你可能感兴趣的:(流水记录方式)