发布于2026-07-19 阅读(0)
扫一扫,手机访问
先说几个关键点:悲观锁的 selectForUpdate() 确实会阻塞,但仅限于数据库行级锁,而且必须在事务内生效。脱离 DB::transaction(),或者没有关闭自动提交,它就可能静默失效,甚至退化成普通查询。乐观锁则完全不依赖数据库锁,靠 version 字段做并发校验,但需要自己拼 where 条件。至于 sharedLock(),它允许多个事务同时读,但会阻塞写操作——不过它防不住“丢失更新”这类问题。下面逐一拆解。

会,但前提是它确实在事务内运行,并且 where 条件命中了索引。否则,要么锁失效,要么直接锁表。一个经典错误是:SQLSTATE[HY000]: General error: 1205 Deadlock found when trying to get lock —— 多个请求同时对同一组记录加锁,但顺序不一致,触发 MySQL 死锁。
DB::transaction() 包裹整个读-改-写流程,不能只给 selectForUpdate() 加事务SELECT ... FOR UPDATE 在可重复读(RR)隔离级别下默认加临键锁(Next-Key Lock),可能锁住不存在但“应该存在”的间隙DB::transaction(function () { $user = User::where('id', 123)->lockForUpdate()->first(); $user->balance -= 100; $user->sa ve();});乐观锁的核心是“先查后验”,不依赖数据库锁,而是靠业务字段(比如 version 或 updated_at)做并发校验。Lara vel 自带的 increment()、decrement() 是原子操作,但本身不带版本检查——你得手动拼 where 条件。
容易踩的坑:$model->version++ + $model->sa ve() 不是原子的,两个请求可能读到相同 version,都写成了 version=2,结果一次更新被覆盖。
whereRaw('version = ?', [$oldVersion]) 做更新前置校验,再用 update() 一次性完成increment() 本身安全,但仅适用于纯数值累加场景(如计数器),无法替代带业务逻辑的“读-改-写”$affected = User::where('id', 123) ->where('version', $expectedVersion) ->update(['balance' => DB::raw('balance - 100'), 'version' => DB::raw('version + 1')]);selectForUpdate() 加排他锁(X Lock),阻止其他事务读写该行;sharedLock() 加共享锁(S Lock),允许其他事务加 S 锁(即并发读),但会阻塞 X 锁(写操作)。两者都只在事务中有效,且都要求 where 条件命中索引。
一个典型误用:把 sharedLock() 当成“读不阻塞”的万能方案——但它并不能防止 A 读、B 写、A 再写导致的覆盖问题(即丢失更新),它只防“写-写冲突”,不防“读-写-写”。
selectForUpdate()sharedLock()WHERE 精确命中索引,否则可能锁表sharedLock() 对应 SELECT ... LOCK IN SHARE MODE,注意某些存储引擎(如 MyISAM)不支持因为 InnoDB 的 UPDATE 语句在执行时会先定位记录并加 X 锁,再判断 WHERE 条件是否满足;若不满足,锁会立刻释放。所以多个请求同时执行 User::where('balance', '>=', 100)->decrement('balance', 100),最终只有第一个成功扣减,其余因条件不满足而跳过——这看起来像乐观锁行为,但底层仍是悲观锁机制。
关键点在于:这不是“无锁重试”,而是“锁了再判,不满足就放”。如果业务需要明确知道是否被抢,不能只靠 affected rows 为 0 就认为失败,得结合具体逻辑判断(比如余额是否真不足)。
decrement() 不会触发模型事件(sa ving/sa ved),如有审计日志等需求,得手动补全实际用哪一种,取决于你能否容忍“重试”、数据库是否支持行锁、以及业务对一致性的容忍边界。悲观锁容易死锁,乐观锁容易重试失败,而看似简单的 update() + where 其实暗藏锁生命周期细节——这些地方,线上出问题时往往最先崩。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8