mysql子查询锁

session 1:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update a set name=(select name from bai where a.id=bai.id) where id=1;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

session 2:

mysql> use test;
Database changed
mysql> update bai set name='ee' where id=10000;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql>

默认的隔离级别是rr,如果session1 单独select是不会阻塞2的,select的会使用快照,update使用当前读,所以在子查询中的select为了防止幻读,就直接不让表有dml了。

<think>嗯,用户想了解MySQL子查询中的“当前读”用法及相关问题。首先,我需要确认“当前读”在MySQL中的具体含义。根据已有的知识,当前读通常与数据库的隔离级别有关,尤其是在可重复读(Repeatable Read)和读已提交(Read Committed)级别下。当前读指的是读取数据的最新提交版本,而不是快照版本。这可能涉及到FOR UPDATE或LOCK IN SHARE MODE这样的机制。 接下来,用户提到子查询,需要结合子查询的上下文来分析。子查询可以出现在SELECT、WHERE等子句中,而当前读可能在事务中用于确保数据的一致性。例如,在事务中使用SELECT ... FOR UPDATE来定行,防止其他事务修改,这时候子查询可能需要获取最新的数据。 然后,我需要查找相关的引用内容。引用[3]提到子查询是嵌套在较大查询中的SQL查询,可以作为另一个SQL语句的数据来源或判断条件。引用[2]讨论了子查询的类型,如标量、多行、多列和相关子查询,这些都可能涉及到当前读的情况,尤其是在处理需要实时数据的场景。 可能的用例包括在事务中更新数据前,先通过子查询获取最新的值,并定相关行。例如,先查询账户余额,然后进行更新,这时候使用FOR UPDATE确保在事务期间数据不被其他事务修改。此时,子查询可能需要使用当前读来获取最新数据。 另外,需要注意隔离级别的影响。在可重复读隔离级别下,普通的SELECT可能会使用快照读,而FOR UPDATE会触发当前读,获取最新数据并加锁。因此,在子查询中使用FOR UPDATE或LOCK IN SHARE MODE可以实现当前读。 还需要考虑性能问题,因为当前读可能会增加锁竞争,影响并发性能。用户可能需要优化查询,减少的范围或时间。 总结步骤:解释当前读的概念,说明在子查询中的使用方法,给出示例,如事务中的SELECT FOR UPDATE子查询,并讨论隔离级别的影响和优化建议。</think>### MySQL子查询中的"当前读"应用解析 #### 一、当前读的核心概念 在InnoDB存储引擎中,"当前读"指事务读取最新已提交数据版本的操作,需要配合行机制实现。主要出现在以下场景: 1. 显式加锁查询:$SELECT ... FOR UPDATE$ 或 $SELECT ... LOCK IN SHARE MODE$[^2] 2. 数据修改语句:$UPDATE/DELETE$语句中的隐式加锁操作[^3] #### 二、子查询中的当前读实现方法 1. **加锁子查询**(8.0+版本支持) ```sql SELECT * FROM orders WHERE amount > ( SELECT AVG(amount) FROM orders FOR UPDATE ); ``` 该示例通过子查询获取实时统计值时定数据[^3] 2. **UPDATE中的嵌套查询** ```sql UPDATE products SET stock = stock - ( SELECT quantity FROM cart_items WHERE item_id = 101 FOR UPDATE ) WHERE product_id = 2001; ``` 此时子查询会触发当前读,确保库存扣减准确性 3. **事务中的关联定** ```sql START TRANSACTION; SELECT @balance:=balance FROM accounts WHERE user_id=1001 FOR UPDATE; UPDATE accounts SET balance = @balance - 1000 WHERE user_id=1001; COMMIT; ``` 通过子查询获取最新余额并定记录[^1] #### 三、注意事项 1. **隔离级别影响**:当前读在READ COMMITTED级别下每次读取新快照,REPEATABLE READ级别下使用首次快照[^3] 2. **范围控制**:使用精确的WHERE条件缩小定范围 3. **死预防**:保持一致的加锁顺序,避免交叉定 4. **性能优化**:复杂子查询应考虑改用JOIN方式实现 #### 四、典型应用场景 1. 金融交易系统余额校验 2. 库存管理系统实时扣减 3. 票务系统座位定 4. 排行榜数据实时统计 $$ \text{等待超时公式}:innodb\_lock\_wait\_timeout = t_{max} \quad (\text{默认50秒}) $$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值