,当我们在MySQL中使用InnoDB表进行“选择更新”时,有没有跳过“锁定行”的方法?
例如:终端t1
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select id from mytable ORDER BY id ASC limit 5 for update;
+-------+
| id |
+-------+
| 1 |
| 15 |
| 30217 |
| 30218 |
| 30643 |
+-------+
5 rows in set (0.00 sec)
mysql>
同时,终端t2:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select id from mytable where id>30643 order by id asc limit 2 for update;
+-------+
| id |
+-------+
| 30939 |
| 31211 |
+-------+
2 rows in set (0.01 sec)
mysql> select id from mytable order by id asc limit 5 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql>
因此,如果我启动一个查询,强制它选择其他行,那就行了。
但是有什么方法可以跳过锁定的行吗?
我想这在并发过程中应该是一个多余的问题,但我没有找到任何解决方案。
编辑:在现实中,我的不同并发进程所做的事情显然非常简单:
因此,我只想选择尚未锁定的行以及myflag_inUse!=1.
下面的链接帮助我理解为什么需要超时,而不是如何避免超时:
mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+-------------------------+
| Variable_name | Value |
+-------------------------+-------------------------+
| innodb_version | 5.5.46 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 5.5.46-0ubuntu0.14.04.2 |
| version_comment | (Ubuntu) |
| version_compile_machine | x86_64 |
| version_compile_os | debian-linux-gnu |
+-------------------------+-------------------------+
7 rows in set (0.00 sec)
发布于 2019-04-16 07:10:23
MySQL 8.0引入了对SKIP LOCKED
和NO WAIT
的支持。
SKIP LOCKED
对于实现作业队列(即批处理队列)非常有用,这样您就可以跳过已被并发事务锁定的锁。
NO WAIT
对于避免等待并发事务释放我们也感兴趣的锁非常有用。
如果没有NO WAIT
,我们要么等待锁被释放(当前持有锁的事务在提交或释放时),要么等待锁获取超时。NO WAIT
充当一个值为0
的锁定超时。
有关SKIP LOCK
和NO WAIT
的更多详细信息。
发布于 2018-03-02 16:46:08
从8.0.1开始的MySQL中现在似乎存在这种情况:
https://mysqlserverteam.com/mysql-8-0-1-using-skip-locked-and-nowait-to-handle-hot-rows/
从MySQL 8.0.1开始,我们将引入跳过锁定修饰符,它可以用于不确定地从表中读取行,同时跳过已锁定的行。这可以被我们的预订系统用来跳过正在等待的订单。例如:
但是,我认为这个版本不一定已经准备好了。
发布于 2015-11-04 07:25:58
不幸的是,到目前为止,似乎无法跳过select中的锁定行以进行更新。
如果我们可以使用像Oracle这样的“用于更新、跳过锁定”的工具,那就太好了。
在我的例子中,并行启动的查询都是完全相同的,在数百万rows...because上包含一个'where‘子句和一个'group’,这些查询需要20到40秒才能运行,这是问题的很大一部分(我已经知道了)。
--临时的而不是最好的--解决方案是移动一些(即:数百万)我不会(直接)使用的行,以减少查询所需的时间。
所以我仍然会有同样的行为,但我会等待更少的时间.
I期望有一种方法不选择select.中锁定的行。
我不把这个标记为答案,所以如果添加(或发现) mysql的一个新子句,我可以稍后接受它.
https://stackoverflow.com/questions/33411620
复制相似问题