加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

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

发布时间:2020-12-12 07:02:47 所属栏目:MsSql教程 来源:网络整理
导读:在SQL数据库中处理并发更新的常见方法是什么? 考虑一个简单的SQL模式(约束和默认值未显示..) create table credits ( int id,int creds,int user_id); 意图是为用户存储某种类型的信用,例如像stackoverflow的声誉。 如何处理该表的并发更新? 几个选项: up
在SQL数据库中处理并发更新的常见方法是什么?

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

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

意图是为用户存储某种类型的信用,例如像stackoverflow的声誉。

如何处理该表的并发更新?
几个选项:

> update credit set creds = 150 where userid = 1;

在这种情况下,应用程序检索当前值,计算新值(150)并执行更新。如果有人在同一时间做同样的事情,就会发生灾难。
我猜想包装当前值的retreival和更新在一个事务将解决,例如开始;从userid = 1的学分中选择凭证;应用程序逻辑来计算新值,更新学分集积分= 160,其中userid = 1;结束;在这种情况下,您可以检查新信用额度是否为0并且只要将其截断为0,如果否定的积分没有意义。
更新学分集合creds = creds – 150其中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的默认数据库类型MyISAM没有。如果你在mysql上使用InnoDB。
>由于您无法控制的原因,交易可能会中止。如果发生这种情况,您的应用程序必须准备从BEGIN WORK开始重新开始。
>您需要将隔离级别设置为SERIALIZABLE,否则第一个select可以读取其他事务尚未提交的数据(事务不像编程语言中的互斥体)。如果并发持续的SERIALIZABLE事务,某些数据库将会发生错误,您必须重新启动事务。
>一些DBMS提供SELECT .. FOR UPDATE,这将锁定通过select进行撤销的行直到事务结束。

将事务与SQL存储过程组合可以使后一部分更容易处理;应用程序只会在事务中调用单个存储过程,如果事务中止,则重新调用它。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读