MySQL锁机制

乐观锁与悲观锁

这是人为提出的概念,是处理并发资源的常见手段,不是MySQL提供的锁机制

悲观锁

悲观锁认为数据处理时总会发生冲突,先上锁再处理数据,策略比较保守,保证了数据处理的安全性,但也降低了效率

悲观锁通常依靠数据库提供的锁机制实现

SET autocommit = 0; # 需要关闭MySQL的自动提交功能
BEGIN;
SELECT nums FROM goods WHERE goods_id = {$goods_id} FOR UPDATE;
UPDATE goods SET nums = nums - {$num} WHERE goods_id = {$goods_id} AND nums > {$num};
COMMIT;

乐观锁

乐观锁认为数据一般情况下不会发生冲突,只有提交数据更新时,才会检测数据是否冲突

如果发现了冲突,则返回错误信息给用户,让用户自己决定如何操作

乐观锁的实现不依靠数据库提供的锁机制,需要我们自己实现,实现方式一般是记录数据版本(通过版本号或者时间戳)

举个例子

CREATE TABLE "goods" (
    "id" bigint(20) unsigned NOT NULL AUCO_INCREMENT COMMENT "ID",
    "goods_id" bigint(20) unsigned DEFAULT "0" COMMENT "商品ID",
    "nums" int(11) unsigned DEFAULT "0" COMMENT "商品库存数量",
    "create_time" datetime DEFAULT NULL COMMENT "创建时间",
    "modify_time" datetime DEFAULT NULL COMMENT "更新时间",
    "version" bigint(20) unsigned DEFAULT "0" COMMENT "版本号",
    PRIMARY KEY ("id"),
    UNIQUE KEY "goods_id" ("goods_id")
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT="商品库存表";

商品购买的过程中,库存数量减少,用乐观锁来避免超卖:

BEGIN;
SELECT nums, version FROM goods WHERE goods_id = {$goods_id};