为啥使用 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 会抛出并发更新错误?

select for update

Django 的 select_for_update 方法是不是与 update 方法一起使用?

既然没有事务 SELECT FOR UPDATE 是没有意义的,而且事务本身使用锁,那么 SELECT FOR UPDATE 的用例是啥?

select..for update