RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 729438
Accepted
AseN
AseN
Asked:2020-10-11 19:52:30 +0000 UTC2020-10-11 19:52:30 +0000 UTC 2020-10-11 19:52:30 +0000 UTC

粒度选择,然后更新

  • 772

有没有办法在选择集上执行选择后更新,这样在两个查询之间不执行来自其他连接的查询,同时不锁定整个表?

任务是平庸的 - 选择 N 条记录然后更新所有记录(几个字段),以便在选择和更新相同记录之间不会在其他连接中并行选择。

诸如 select for update 之类的锁不适合,因为如果在索引字段的“空间”上设置了条件,它们只会锁定带有索引的记录。

有没有足够的方法来解决这个问题?

更新:

请求看起来像这样(它们都在触发器中):

START TRANSACTION ;

        DROP TABLE IF EXISTS TempTable;
        CREATE TEMPORARY TABLE TempTable AS(
            SELECT units.id AS id, units.authkey AS authkey
            FROM availablePublicUnitsView units
                LEFT JOIN media_info
                    ON units.id=media_info.unit_id AND media_info.media_id=mediaId
            WHERE media_info.media_id IS NULL
            LIMIT unitsCount
            #FOR UPDATE
        );

        UPDATE units SET reserved=true, last_usage_time=NOW(), reservation_hash=reservationHash
        WHERE id IN (SELECT id from TempTable) AND reserved=false;

        SELECT * FROM TempTable;

COMMIT ;

我不是 SQL 专家,所以如果我做错了什么,我会很高兴听到它是什么。

mysql
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    AseN
    2020-10-18T22:38:33Z2020-10-18T22:38:33Z

    结果,在进行了几次负载测试后,不使用临时表(每次都重新创建,占用大部分时间)但使用锁进行更新的选项被证明是最佳选择。

    首先,所有必要的记录都用 SHA-256 散列形式的选择“密钥”更新(算法不是关键的),然后选择所有具有设置散列的记录,但在事务完成之后。该解决方案运行速度非常快,并且阻塞最小。

    同样重要的是要注意availablePublicUnitsView选择视图中的数据,按随机顺序(ORDER BY RAND)预先排序,将锁减少到几乎为零。

    CREATE PROCEDURE select_and_reserve_units(
        IN unitsCount INT,
        IN mediaId VARCHAR(40),
        IN reservationHash BINARY(64))
    BEGIN
    
    START TRANSACTION ;
    
        UPDATE units SET reserved=true, last_usage_time=NOW(), reservation_hash=reservationHash
        WHERE id IN (
    
            SELECT units.id
            FROM availablePublicUnitsView units
                LEFT JOIN media_info
                    ON units.id=media_info.unit_id AND media_info.media_id=mediaId
            WHERE media_info.media_id IS NULL    
            FOR UPDATE
    
        ) LIMIT unitsCount;
    
    COMMIT ;
    
    SELECT unit.id AS id, unit.authkey AS authkey FROM units
    WHERE reservation_hash=reservationHash AND reserved=true;
    
    END;//
    

    PS 显然,是时候切换到 PostgreSQL 了……

    • 2
  2. Olga
    2020-10-14T16:10:20Z2020-10-14T16:10:20Z

    我已经明白了,有必要禁止在相同的记录上并行执行这些请求吗?

    尝试更改隔离级别。因此使用 SELECT FOR UPDATE。

    将事务隔离级别设置为未提交;

    READ UNCOMMITTED - 允许其他人读取数据,即使事务未提交。

    或 REPEATABLE READ - 应该只阻止可更改的行。

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5