- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
首先,我完全看不出我怎么会出现任何死锁,因为我没有使用显式锁定,只涉及一个表,每个表都有一个单独的进程要插入、选择和更新行,一次只插入或更新一行,并且每个进程很少(可能一分钟一次)运行。
这是一个电子邮件队列:
CREATE TABLE `emails_queue` (
`id` varchar(40) NOT NULL,
`email_address` varchar(128) DEFAULT NULL,
`body` text,
`status_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`status` enum('pending','inprocess','sent','discarded','failed') DEFAULT NULL,
KEY `status` (`status`),
KEY `status_time` (`status`,`status_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
生成过程响应某些用户操作,但大约每 90 秒一次,对表执行一次插入,将状态设置为“待处理”。
有一个监控过程,每分钟检查一次“待处理”和“失败”电子邮件的数量是否过多。运行时间不到一秒钟,而且从未给我带来任何麻烦。
发送进程每分钟都会抓取所有待处理的电子邮件。它循环遍历一次一封电子邮件,将其状态设置为“处理中”,尝试发送它,最后将其状态相应地设置为“已发送”、“已丢弃”(它有理由决定一封电子邮件不应该发出),或“失败”(被 SMTP 系统拒绝)。
设置状态的语句不正常。
UPDATE emails_queue SET status=?, status_time=NOW() WHERE id=? AND status = ?
也就是说,只有当当前状态已经达到我认为的状态时,我才会更新状态。在这个机制之前,我不小心启动了两个发送进程,它们都会尝试发送相同的电子邮件。现在,如果发生这种情况,一个进程会成功地将电子邮件从“待处理”移动到“处理中”,但第二个进程会更新零行,意识到存在问题,然后跳过该电子邮件。
问题是,大约有 100 次更新完全失败!我得到 com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock;尝试重启事务
什么?
这是唯一发生这种情况的表和唯一查询,并且它只发生在生产中(以最大限度地增加调查难度)。
只有两件事看起来很不寻常:(1) 更新参与 WHERE 子句的列,以及 (2) status_time 的(未使用的)自动更新。
我正在寻找任何建议或诊断技术。
最佳答案
首先,死锁不依赖于显式锁定。 MySQL 的 LOCK TABLE 或使用非默认事务隔离模式不需要有死锁。如果您从不使用显式事务,您仍然会遇到死锁。
死锁很容易发生在单个表上。最常见的是来自单个热表。
如果您的所有事务都只执行单行插入,则甚至可能会发生死锁。
如果你有,可能会发生死锁
不明显的是,大多数时候,单行插入或更新涉及多个锁。这样做的原因是二级索引在插入/更新期间也需要锁定。
SELECT 不会锁定(假设您使用的是默认隔离模式,并且没有使用 FOR UPDATE)所以它们不可能是原因。
SHOW ENGINE INNODB STATUS 是你的 friend 。它会给你一堆(诚然非常困惑)关于死锁的信息,特别是最近的。
关于mysql - 解释莫名其妙的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5970210/
我有类似下面的代码: ... id: myComponent signal updateState() property variant modelList: [] Repeater { mo
我正在处理一些我无法展示的私有(private)代码,但我已经制作了一些示例代码来描述我的问题: 主.c: #include #include #include #include typede
这个问题在这里已经有了答案: 关闭10 年前。 Possible Duplicate: what are the differences in die() and exit() in PHP? 我想
在编写 Perl 模块时,在模块内部使用 croak/die 是一个好习惯吗? 毕竟,如果调用者不使用 eval block ,模块可能会使调用它的程序崩溃。 在这些情况下,最佳做法是什么? 最佳答案
我有一些搜索线程正在存储结果。我知道当线程启动时,JVM native 代码会代理在操作系统上创建新 native 线程的请求。这需要 JVM 之外的一些内存。当线程终止并且我保留对它的引用并将其用作
我刚刚花了很多时间调试一个我追溯到 wantarray() 的问题。 .我已将其提炼为这个测试用例。 (忽略 $! 在这种情况下不会有任何有用信息的事实)。我想知道为什么wantarray在第二个示例
我看到一些代码是这样做的: if(something){ echo 'exit from program'; die; } ...more code 和其他只使用 die 的人: if
我正在尝试将此表格用于: 如果任何 $_POST 变量等于任何其他 $_POST 变量抛出错误。 如果只有几个,那不是问题,但我有大约 20 个左右所以如果我想这样做,我将不得不像这样 但这
每次我运行: hadoop dfsadmin -report 我得到以下输出: Configured Capacity: 0 (0 KB) Present Capacity: 0 (0 KB) DFS
我是一名优秀的程序员,十分优秀!