gpt4 book ai didi

sql - 如何处理数据库中的并发更新?

转载 作者:行者123 更新时间:2023-12-03 09:17:12 26 4
gpt4 key购买 nike

在SQL数据库中处理并发更新的常用方法是什么?

考虑一个简单的SQL模式(未显示约束和默认值。),例如

create table credits (
int id,
int creds,
int user_id
);

目的是为用户存储某种信用。类似stackoverflow的声誉。

如何处理对该表的并发更新?
一些选择:
  • update credits set creds= 150 where userid = 1;
    在这种情况下,应用程序检索当前值,计算新值(150)并执行更新。如果其他人在同一时间做同样的事,那将带来灾难。
    我猜想包装当前值的回归并在交易中更新将解决这个问题,例如Begin; select creds from credits where userid=1; do application logic to calculate new value, update credits set credits = 160 where userid = 1; end;在这种情况下,您可以检查新信用是否小于0,如果负信用没有意义,则将其截断为0。
  • update credits set creds = creds - 150 where userid=1;
    这种情况无需担心并发更新,因为DB会处理一致性问题,但存在的缺点是信誉很可能变成负面,这对于某些应用程序可能没有意义。

  • 简而言之,处理上述(非常简单)问题的可接受方法是什么,如果数据库抛出错误怎么办?

    最佳答案

    使用交易:

    BEGIN WORK;
    SELECT creds FROM credits WHERE userid = 1;
    -- do your work
    UPDATE credits SET creds = 150 WHERE userid = 1;
    COMMIT;

    一些重要的注意事项:
  • 并非所有数据库类型都支持事务。特别是,MySQL的旧默认数据库引擎(版本5.5.5之前的默认数据库引擎)MyISAM不会。如果您使用的是mysql,请使用InnoDB(新的默认值)。
  • 事务可能会由于无法控制的原因而中止。如果发生这种情况,您的应用程序必须准备从头开始重新开始。
  • 您需要将隔离级别设置为SERIALIZABLE,否则第一个选择可以读取其他事务尚未提交的数据(事务不像编程语言中的互斥锁一样)。如果同时存在正在进行的SERIALIZABLE事务,则某些数据库将引发错误,并且您必须重新启动事务。
  • 一些DBMS提供SELECT .. FOR UPDATE,它将锁定select检索的行,直到事务结束。

  • 将事务与SQL存储过程结合在一起可以使后者更易于处理;应用程序将仅在事务中调用一个存储过程,并在事务中止时重新调用它。

    关于sql - 如何处理数据库中的并发更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1195858/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com