mysql的锁的一个问题,for update用法。

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