为啥使用 SELECT FOR UPDATE?
Posted
技术标签:
【中文标题】为啥使用 SELECT FOR UPDATE?【英文标题】:Why use SELECT FOR UPDATE?为什么使用 SELECT FOR UPDATE? 【发布时间】:2015-03-08 02:16:07 【问题描述】:我对我们使用SELECT FOR UDPATE
的目的有疑问?它的具体作用是什么?
我有 2 个表,我需要从表中选择行并更新相同的行。
例如:
选择查询
SELECT * from t1 WHERE city_id=2 for update
更新查询
UPDATE t1 SET final_balance = final_balance - 100 WHERE city_id ='2'
我的问题 - 这真的会在我的更新完成之前锁定读取操作吗,或者它到底处理了什么?
我的想法是在我的更新完成之前,没有人可以读取/更新这些行。
谢谢!
【问题讨论】:
为什么不阅读手册? dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html "我的想法是没有人可以从这些行读取/更新" - 这是错误的。行锁不会阻止 读取 访问(例如,没有for update
的普通 select
)
【参考方案1】:
SELECT ... FOR UPDATE
将使用写(独占)锁锁定记录,直到事务完成(提交或回滚)。
要选择一条记录并确保在更新之前它不会被修改,您可以启动一个事务,使用SELECT ... FOR UPDATE
选择记录,进行一些快速处理,更新记录,然后提交(或回滚)事务.
如果你在事务之外使用SELECT ... FOR UPDATE
(autocommit ON),那么锁仍然会立即释放,所以一定要使用事务来保留锁。
为了性能,不要让事务保持打开很长时间,所以应该立即进行更新。
【讨论】:
事务不保证锁吗?换句话说,SELECT ... FOR UPDATE 只有在事务具有低隔离级别(如 read_uncommit)时才有意义? 在我看来,SELECT ... FOR UPDATE 通常应用在“已读”隔离级别下。 @J.J.Beam 事务保证锁定UPDATE
,但不保证锁定SELECT
(读取)。因此,如果您在事务开始时执行 SELECT ...
而没有 FOR UPDATE
然后在事务中稍后使用选定的行信息进行更新,则另一个事务可能更新了您之前查询的行在您的交易中。因此,如果您以后需要使用查询的行,则必须在事务中使用SELECT ... FOR UPDATE
。阅读:dev.mysql.com/doc/refman/8.0/en/…以上是关于为啥使用 SELECT FOR UPDATE?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我们在 Oracle SQL 中需要 SELECT FOR UPDATE?
为啥 SELECT FOR UPDATE SKIP LOCKED 时 PostgreSQL 会抛出并发更新错误?
Django 的 select_for_update 方法是不是与 update 方法一起使用?
既然没有事务 SELECT FOR UPDATE 是没有意义的,而且事务本身使用锁,那么 SELECT FOR UPDATE 的用例是啥?