Mysql 5.7,InnoDB引擎,“行锁”的问题。
如一个网络上的拍卖行为,两人可同时(我们假定数据库的时间精度精确到秒的话,mysql就是这样)出价很常见,这样的情况会产生一些特别的问题。
比如每次出价都是先从数据库中取出当前最新价,然后加上此用户出价的幅度,就是新的价格,并更新最新价格。
而假如这个存储过程的执行要0.1s,假定从0时刻开始A用户出了价。
也就是说次存储过程从此刻起要先从数据库中取出当前价,需要0.1s的时间里执行此存储过程,最后更新数据库里的最新价格。
那么问题来了,如果B用户在0.05s时刻的时候出价了会怎样呢?
显然地,A用户尚未来得及将价格改变,但已经在执行操作了。
而B用户拿到的是一个“旧”的价格,是不合理的,即“脏读”。
这种情况就应该使用数据库锁了,对于这种情况,mysql当然是首选InnoDB引擎,行锁来解决。
在这里,我就简单大致展示出此存储过程即可。简单易懂(改装过了,已脱敏,自己适当辨别)。
CREATE DEFINER = 'root'@'localhost' PROCEDURE mydb.mybid(IN i_uid INT(11), IN shelvesPk INT(11), IN i_bid_time DATETIME, IN i_is_auto BIT, OUT o_result INT, OUT o_isUseBonus INT, OUT o_period INT, OUT o_afterPrice DECIMAL(10,2), OUT o_lastBadeUid INT) COMMENT '商品的出价行为' label:BEGIN #开始存储过程 START TRANSACTION; #得到上一次出价的信息 SELECT hsr.cur_price,hsr.last_bade_uid INTO tempCurPrice, tempLastBadeUid from shelves shv WHERE shv.pk = shelvesPk FOR UPDATE; #第一处要注意的 #更新hit_shelves_record的cur_price、last_bade_uid UPDATE hit_shelves_record hsr set hsr.cur_price = afterPrice,hsr.last_bade_uid = i_uid where hsr.pk = i_hit_shelves_pk; IF ROW_COUNT() != 1 THEN set o_result = -20; ROLLBACK; LEAVE label; end IF; #返回信息里带有 IF t_error = 1 THEN set o_result = -20; ROLLBACK; ELSE set o_result = 0; set o_period = curPeriod; set o_afterPrice = afterPrice; set o_lastBadeUid = i_uid; COMMIT; END IF; END