我已经阅读并测试了MySQL的InnoDB中的行级锁,但我仍然很难说“我知道锁在MySQL中是如何工作的”!
以下是我的测试数据:
mysql> select * from lockable;
+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | A | A |
| 2 | A | B |
| 3 | A | C |
| 4 | B | A |
| 5 | B | B |
| 6 | B | C |
| 7 | C | A |
| 8 | C | B |
| 9 | C | C
我使用MySQL中的行锁定(事务)来创建作业队列。使用的引擎是InnoDB。
SQL查询
START TRANSACTION;
SELECT *
FROM mytable
WHERE status IS NULL
ORDER BY timestamp DESC LIMIT 1
FOR UPDATE;
UPDATE mytable SET status = 1;
COMMIT;
根据这个,
The problem with SELECT FOR UPDATE is that it usually creates a single synchronization point for
说SELECT FOR UPDATE设置一个IX锁。IX锁是意图排他锁,当发出时它意味着“事务T打算在扫描行上设置X(排它)锁”。这意味着在SELECT FOR UPDATE成功之前,它必须先获得IX,然后才能获得X。MySQL术语表表示,关于意图排他性锁:
意图锁定
一种适用于表级别的锁,用于指示事务打算在表中的行上获取什么样的锁。不同的事务可以在同一表上获取不同类型的意图锁,,但是获取表上的意图排他(IX)锁的第一个事务阻止其他事务获取表上的任何S或X锁。相反,获取表上的意图共享(IS)锁的第一个事务阻止其他事务获取该表上的任何X锁。两阶段进程允许按顺序解析锁请求,而不阻塞兼容的锁和相应
我有一个由不同线程同时读取的表。
每个线程必须选择100行,在每行上执行一些任务(与数据库无关),然后必须从表中删除选定的行。
使用以下查询选择行:
SELECT id FROM table_name FOR UPDATE;
我的问题是:如何忽略(或跳过)以前在MySQL中使用select语句锁定的行?
"SELECT ... FOR UPDATE"锁是否加入了MySQL中的行?
如果是的话,是否有可能禁用这种行为?
文档中没有这方面的内容。我已经看到Oracle支持"SELECT ... FOR UPDATE OF table_name",其中table_name是主表,或者是受影响的行将被锁定的连接表之一,但我从未见过在MySQL上下文中提到过这一点。
我不明白两个重复查询,每个查询使用主键删除单个表上的一行,怎么会死锁。有谁能解释一下吗?
在我看来,其中一个事务应该获得锁,而另一个事务则必须等待。
以下是死锁报告,以及查询:
Fri Jun 01 2012 13:50:23
*** (1) TRANSACTION:
TRANSACTION 3 1439005348, ACTIVE 0 sec, process no 22419, OS thread id 1166235968 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), hea
SQL Server:如何持有select查询的排它锁?对于mysql,
select * from Employee e
where e.id=123
for update
其他并发事务无法读取或写入所选行。
如何在SQL server上实现同样的功能?
SELECT *
FROM Employee e
WITH (HOLDLOCK, ROWLOCK)
WHERE e.id = 123;
对于(HOLDLOCK,row LOCK ),它是否持有所选行的读锁定?有了读锁,其他事务仍然可以读取锁定的行,对吗?
我有一个有超过160百万条目的表,它有一个错误的表引擎,所以我要改变引擎。当我在没有做任何准备的情况下做这件事时,由于缓冲区大小,由于行锁太多,我会得到一个错误。
mysql> ALTER TABLE foobar ENGINE=MyISAM;
ERROR 1206 (HY000): The total number of locks exceeds the lock table size
现在,我希望在此操作之前锁定整个表,然后解锁整个表。
mysql> LOCK TABLES foobar WRITE;
我的问题是: mysql服务器是否注意到一个表锁已经处于活动状态并跳过了行
这类问题已经张贴了几次,但在以下情况下所提供的解决办法并不理想。在第一个查询中,我选择执行第一个查询时已知存在的表名。然后,在循环遍历它们时,我希望查询所选表中的记录数,但前提是它们仍然存在。问题是,在循环期间,一些表被另一个脚本删除。例如:
SELECT tablename FROM table
-- returns say 100 tables
while (%tables){
SELECT COUNT(*) FROM $table
-- by the time it gets to the umpteenth table, it's been dropped
我有一个简单的函数,如下所示
$q = "SELECT * FROM tbl1 WHERE proc=0";
$r = mysql_query($q);
if (mysql_num_rows($r) > 0) {
while ($row = mysql_fetch_assoc($r)) {
mysql_query('UPDATE SET proc=0 FROM tbl1 id=' . $row['id']);
mysql_query("INSERT INTO tbl2(value,tbl_id
我不清楚(通过阅读MySQL文档)下面的查询是在MySQL 5.1上的INNODB表上运行,是为数据库在内部更新的每一行(总共5000行)创建写锁,还是锁定批处理中的所有行。由于数据库的负载非常重,因此这一点非常重要。
UPDATE `records`
INNER JOIN (
SELECT id, name FROM related LIMIT 0, 5000
) AS `j` ON `j`.`id` = `records`.`id`
SET `name` = `j`.`name`
我希望它是每行的,但由于我不知道有什么方法可以确保它是这样的,我决定请教一个有更深知识的人。如果不是这样
每隔一段时间我就会收到一个mysql错误。错误是
Deadlock found when trying to get lock; try restarting transaction
查询为
var res = cn.Execute("insert ignore into
Post(desc, item_id, user, flags)
select @desc, @itemid, @userid, 0",
new { desc, itemid, userid });
这个问题究竟是如何导致它的呢?在谷歌搜索时,我看到了一些关于查询如何占用很长的锁行
我有MySQL (InnoDB)表和列is_locked,它显示记录的当前状态(它现在是否由系统处理)。
另一方面,我有许多节点执行SELECT * FROM table_name WHERE is_locked = 0,然后处理这个表中的行。
在我的代码中,我这样做:
系统从DB (SELECT * FROM table_name WHERE is_locked = 0)获取行
系统通过命令UPDATE table_name SET is_locked = 1 WHERE id = <id>锁定行
问题:节点工作速度非常快,所有节点都可能得到相同的行,然后第一个节
我有一张桌子,名叫spot和reservation。spot包含spot_id和spot_status列。对于预订过程,我启动一个事务,然后使用此查询获取特定行的锁。我正在使用php和mysql。
//start transaction
SELECT * FROM spot WHERE spot_id = $id FOR UPDATE ;
//if this query is successful then
1. set spot status to 1
2. insert corresponding values in reservation table.
and the
我正在编写一些代码,它使用行级锁定和MySQL (innodb后端)。
伪码是:
START TRANSACTION
SELECT * FROM foo WHERE foocondition FOR UPDATE
UPDATE foo set bar=value WHERE foocondition
COMMIT
我在mysql文档中找不到提交后持有的锁的信息。
我是否必须在提交后执行“解锁表”,还是它是隐式的?答案应该是“不”,但我想得到有关的反馈。