- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下两个事务导致死锁:
交易 1:
SELECT *
FROM bots b
WHERE b.status = :available
AND (b.last_checked_at IS NULL OR b.last_checked_at < :fiveMinsAgo)
ORDER BY b.last_checked_at ASC
LIMIT 1
FOR UPDATE
*AND* (I don't think that this statement is part of the issue)
UPDATE bots b
SET b.last_checked_at = :now
WHERE b.id = :botId
交易 2:
SELECT b.*, bu.*
FROM bots b
LEFT JOIN bot_users bu ON bu.id = b.assigned_to_bot_user_id
WHERE b.currency = :currency
AND (b.status = :available OR (b.status = :reserved AND bu.last_action_at < :threeMinsAgo))
AND ((b.slot_count - b.items_count) >= :amount)
ORDER BY b.keys_count ASC, b.id ASC
LIMIT 1
FOR UPDATE
*OR*
SELECT b.*, bu.*
FROM bots b
LEFT JOIN bot_users bu ON bu.assigned_bot_id = b.id
WHERE b.currency = :currency
AND (b.status = :available OR (b.status = :reserved AND bu.last_action_at < :threeMinsAgo))
AND (b.keys_count >= :amount)
ORDER BY b.keys_count DESC, b.id ASC
LIMIT 1
FOR UPDATE
*AND*
UPDATE bots SET status = :reserved WHERE id = :id
说明:
事务 #1 正在选择 1 个可用且在过去 5 分钟内未检查过的机器人,对其进行检查,然后更新 last_checked_at 字段。
交易#2(案例 1)选择 1 个机器人,该机器人处理某种货币,状态为可用或保留且“已过期”(3 分钟内没有用户操作),并且有足够的可用插槽。
交易#2(案例 2)选择 1 个机器人,该机器人处理某种货币,状态为可用或保留且“已过期”(3 分钟内没有用户操作),并且拥有足够的 key 来满足请求的金额。
注释:
b.keys_count、b.currency、b.status都有索引。
死锁示例:
------------------------
LATEST DETECTED DEADLOCK
------------------------
2014-07-04 20:33:11 7fc46f270700
*** (1) TRANSACTION:
TRANSACTION 1657246652, ACTIVE 0 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1184, 36 row lock(s)
MySQL thread id 30422870, OS thread handle 0x7fc46f437700, query id 1217244940 10.0.88.8 mydb Creating sort index
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 4752665 page no 3 n bits 176 index `PRIMARY` of table `mydb`.`bots` trx id 1657246652 lock_mode X locks rec but not gap waiting
*** (2) TRANSACTION:
TRANSACTION 1657246644, ACTIVE 0 sec updating or deleting
mysql tables in use 1, locked 1
10 lock struct(s), heap size 2936, 37 row lock(s), undo log entries 1
MySQL thread id 30422999, OS thread handle 0x7fc46f270700, query id 1217244943 10.0.88.8 mydb updating
UPDATE bots SET status = 1 WHERE id = 19
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 4752665 page no 3 n bits 176 index `PRIMARY` of table `mydb`.`bots` trx id 1657246644 lock_mode X locks rec but not gap
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 4752665 page no 6 n bits 168 index `status_idx` of table `mydb`.`bots` trx id 1657246644 lock_mode X locks rec but not gap waiting
*** WE ROLL BACK TRANSACTION (1)
看起来查询锁定了大部分行,而不仅仅是某一行。
防止这些死锁的最佳方法是什么?最好不要在事务 #1 中使用 FOR UPDATE,然后尝试使用还包括其他条件的基于 ID 的选择来获取锁?例如:
SELECT *
FROM bots b
WHERE b.status = :available
AND (b.last_checked_at IS NULL OR b.last_checked_at < :fiveMinsAgo)
ORDER BY b.last_checked_at ASC
LIMIT 1
SELECT *
FROM bots b
WHERE b.id = :idSelectedAbove
AND b.status = :available
AND (b.last_checked_at IS NULL OR b.last_checked_at < :fiveMinsAgo)
FOR UPDATE
这显然会在一定比例的时间内失败,具体取决于各种因素。
使用 ORDER BY, FOR UPDATE 时有没有办法只锁定一行?
最佳答案
考虑使用 GET_LOCK()
模拟记录锁并废弃 FOR UPDATES
;
选择一个特定于您想要锁定的行的名称。例如“bot_id_1”
。
调用SELECT GET_LOCK('bot_id_1',30)
来锁定名称'bot_id_1'
..如果该名称可用,它将返回1并设置锁定,如果30秒后锁不可用则返回0(第二个参数是超时时间)。
完成后使用 SELECT RELEASE_LOCK('bot_id_1')
。
注意;您必须在每个事务中使用相同的名称,并且在事务中再次调用 GET_LOCK()
将释放之前设置的锁定。
关于mysql - 使用 SELECT/LIMIT 1/FOR UPDATE 时避免死锁的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25037476/
我们已经有一个使用 AnyEvent 的库。它在内部使用 AnyEvent,并最终返回一个值(同步 - 不使用回调)。有什么方法可以将这个库与 Mojolicious 一起使用吗? 它的作用如下: #
我想从 XSD 文件生成带有 JAXB 的 Java 类。 问题是,我总是得到一些像这样的类(删除了命名空间): public static class Action { @X
我有一个关于 html 输入标签或 primefaces p:input 的问题。为什么光标总是自动跳转到输入字段。我的页面高度很高,因此您需要向下滚动。输入字段位于页面末尾,光标自动跳转(加载)到页
我今天在考虑面向对象设计,我想知道是否应该避免 if 语句。我的想法是,在任何需要 if 语句的情况下,您都可以简单地创建两个实现相同方法的对象。这两个方法实现只是原始 if 语句的两个可能的分支。
String graphNameUsed = graphName.getName(); if (graphType.equals("All") || graphType.equals(
我有一张友谊 table CREATE TABLE IF NOT EXISTS `friendList` ( `id` int(10) NOT NULL, `id_friend` int(10
上下文 Debian 64。Core 2 二人组。 摆弄循环。我使用了同一循环的不同变体,但我希望尽可能避免条件分支。 但是,即使我认为它也很难被击败。 我考虑过 SSE 或位移位,但它仍然需要跳转(
我最近在 Java 中创建了一个方法来获取字符串的排列,但是当字符串太长时它会抛出这个错误:java.lang.OutOfMemoryError: Java heap space我确信该方法是有效的,
我正在使用 (C++) 库,其中需要使用流初始化对象。库提供的示例代码使用此代码: // Declare the input stream HfstInputStream *in = NULL; tr
我有一个 SQL 查询,我在 WHERE 子句中使用子查询。然后我需要再次使用相同的子查询将其与不同的列进行比较。 我假设没有办法在子查询之外访问“emp_education_list li”? 我猜
我了解到在 GUI 线程上不允许进行网络操作。对我来说还可以。但是为什么在 Dialog 按钮点击回调上使用这段代码仍然会产生 NetworkOnMainThreadException ? new T
有没有办法避免在函数重定向中使用 if 和硬编码字符串,想法是接收一个字符串并调用适当的函数,可能使用模板/元编程.. #include #include void account() {
我正在尝试避免客户端出现 TIME_WAIT。我连接然后设置 O_NONBLOCK 和 SO_REUSEADDR。我调用 read 直到它返回 0。当 read 返回 0 时,errno 也为 0。我
我正在开发 C++ Qt 应用程序。为了在应用程序或其连接的设备出现故障时帮助用户,程序导出所有内部设置并将它们存储在一个普通文件(目前为 csv)中。然后将此文件发送到公司(例如通过邮件)。 为避免
我有一组具有公共(public)父类(super class)的 POJO。这些存储在 superclass 类型的二维数组中。现在,我想从数组中获取一个对象并使用子类 的方法。这意味着我必须将它们转
在我的代码中,当 List 为 null 时,我通常使用这种方法来避免 for 语句中的 NullPointerException: if (myList != null && myList.size
我正在尝试避免客户端出现 TIME_WAIT。我连接然后设置 O_NONBLOCK 和 SO_REUSEADDR。我调用 read 直到它返回 0。当 read 返回 0 时,errno 也为 0。我
在不支持异常的语言和/或库中,许多/几乎所有函数都会返回一个值,指示其操作成功或失败 - 最著名的例子可能是 UN*X 系统调用,例如 open( ) 或 chdir(),或一些 libc 函数。 无
我尝试按值提取行。 col1 df$col1[col1 == "A"] [1] "A" NA 当然我只想要“A”。如何避免 R 选择 NA 值?顺便说一句,我认为这种行为非常危险,因为很多人都会陷入
我想将两个向量合并到一个数据集中,并将其与函数 mutate 集成为 5 个新列到现有数据集中。这是我的示例代码: vector1% rowwise()%>% mutate(vector2|>
我是一名优秀的程序员,十分优秀!