前言

以前写过相关的, 但这篇主要讲一下概念. 帮助理解

Entity Framework with MySQL 学习笔记一(乐观并发)

Asp.net core 学习笔记 ( ef core transaction scope & change level )

sql server 学习笔记 (nested transaction 嵌套事务)

SQL Server中锁与事务隔离级别 (深入浅出的文章, 以后写事务隔离级别可以参考, 借方这里先)

并发与事务

并发是指在同一个时间线上, 多人一起做事情. (比如我在修改一个文档, 你也在修改同一个文档)

在做信息处理的时候, 我们有一个"事务"的概念. 我们可以把它理解成一个信息处理的 "过程".

比如:

在信息处理的时候, 最常见的情况是这样的.

step1: 需要从数据库拿一些信息出来

step2: 依据这些信息做逻辑判断, 逻辑计算, 结合新的 input, 得出最终要 insert/update 的数据

step3: 把新的数据 insert/update to 数据库

这 3 个 step 就是一个过程, 也就是一个事务.

并发的意思就是说, 在同一个时间上, 有很多人在做着许许多多的事务.

数据库对事务有一个原子性规则, 在一个事务中, 可以读读写写多次, 如果间中发生任何问题, 事务会回滚, 测回所有写入的资料 (当然我们也可以在事务任何时候手到回滚.)

并发诞生的问题

在进行一个事务的时候, 我们希望不被任何其它事务"影响", 不然就乱了套了.

比如,

step 1: 从数据库拿出了数据.

step 2: 通过数据做逻辑计算

step 2.5: 这时另一个事务修改了我们 step 1 拿出来的数据.

这个我们 step 2 的逻辑计算就不准确了.

从而也导致了我们 step 3 update 进去的资料是错误的.

这就是并发导致的问题.

解决并发的问题

为什么会乱? 因为没有规则, 所以需要制定规则

一个最简单的规则, 单线程. 让每一个事务都排队. 一个一个处理.

这样就没有并发了咯. 但这当然不行, 太慢了丫. 所以 SQL Server 做了很多不同的 Lock 和 不同的 IsolationLevel 来适量的控制并发的情况.

规则

读了就不能写

如果我们细看刚才的 step 1,2,3

它有 2 个点很重要, 第一就是读取出来的数据, 在事务结束以前都不可以被其它事务修改.

比如我 SELECT Name FROM Person WHERE Id = 1

SQL Server 就会把这条 row 锁上, 不让其它事务 update/delete 它 (其它事务就排队, 等我完成了才能修改)

如果我 SELECT Name FROM Person WHERE Age > 10

那么 SQL Server 会锁更大的范围, 同时也不能 insert Age > 10 的 row

锁的范围越大, 受影响的事务就越多, 排队的事务多就以为着慢. 就回到了最初单线方案的问题.

所以这里就是一个我们需要自己控制的 trade-off.

写了就不能读

另外一个角度就是, 在一个事务过程中, 也许我们会多次读读写写.

而在我写入新数据后, 但事务还没有结束前, 这些新数据是不允许被其它事务读取的.

因为可能最终因为某些原因, 我想取消整个事务. 所以就有了一个反向, 写了就不能读的锁机制.

一样的道理, 锁的越多排队就越多就越慢.

死锁

由于我们允许事务同时处理 (只是中间加了一些规则), 事务进行到一般的时候有可能会突然去排队.

而这个排队会依赖另一个事务的结束, 好死不死遇到循环依赖...那么就死锁了.

我等你, 你等我. SQL Server 会发现这个死锁的情况, 然后自动干掉其中一个事务, 去解锁.

但是我们应该要尽可能在业务层级上去避免这种事情的诞生. 不然又影响数据库性能了.

总结 & 乐观并发

并发的本质就是为了快, 缺乏管理, 导致了混乱.

快是我们追求的, 不要乱也是我们追求的, 鱼与熊掌不能兼得, 所以要懂得 trade-off.

乐观并发

上面我们说的各种锁的机制都是属于悲观并发.

有一种叫乐观并发的规则. 它可以在不锁 (不用排队) 的情况下做到一定层度的管理规则 (解决乱的问题)

举例, 我们想做一个事务处理

step 1: 读取资料

step 2: 做逻辑计算

step 3: update 数据

一般上我们需要用事务去完成上面 3 个步骤. 但是乐观并发不用.

它就跑语句, 读, 然后计算, 然后 update.

回到并发的问题, 如果间中有其它人对数据做了修改怎么办?

它有一个前提, 读 1 row, update 同一个 row. 这种情况下才可以用乐观并发机制, 超出这个范围还是得用事务和锁.

在 row 里面加入一个 row version column 做 version control.  每当 row update 的时候 row version 就修改

然后在 udpate 的时候判断 row version 是否和上一次获取的一样.

如果一样就表示期间没有人修改过资料. 如果不一样就更新失败.

这是一个很聪明的机制, 因为这种场景是最多的. 用一个巧思来解决总比锁的成本小很多. 但是它也只能解决简单的情况, 遇到复杂一些的最终还是得锁的.

SQL Server – Concurrency 并发控制的更多相关文章

  1. 数据库并发控制及SQL Server的并发控制机制

    在多用户和网络环境下,数据库是一个共享资源,多个用户或应用程序同时对数据库的同一数据对象进行读写操作,这种现象称为对数据库的并发操作.显然并发操作可以充分利用系统资源,提高系统效率.虽然如此,但是如果 ...

  2. 第0/24周 SQL Server 性能调优培训引言

    大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...

  3. SQL Server 内存中OLTP内部机制概述(二)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...

  4. SQL Server 性能调优培训引言

    原文:SQL Server 性能调优培训引言 大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤 ...

  5. SQL Server 一致性读

    我们在Oracle和MySQL数据库中已经对一致性读的概念比较熟悉了,但是在SQL Server中却鲜少提及,但SQL Server自2005版本以来其实也实现了一致性读,几乎所有关系型数据库产品的一 ...

  6. sql server性能调优

    转自:https://www.cnblogs.com/woodytu/tag/%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98%E5%9F%B9%E8%AE%AD/defaul ...

  7. Microsoft SQL Server中的事务与并发详解

    本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一 ...

  8. 再谈SQL Server中日志的的作用

    简介     之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用.如果您没有看过我之前的文章,请参阅:     浅谈SQL Server ...

  9. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  10. SQL Server 2014新特性探秘(1)-内存数据库

    简介    SQL Server 2014提供了众多激动人心的新功能,但其中我想最让人期待的特性之一就要算内存数据库了.去年我再西雅图参加SQL PASS Summit 2012的开幕式时,微软就宣布 ...

随机推荐

  1. 在该serializer中使用source参数指定序列化时使用的字段的choices选项

    在序列化中获取time_unit字段的中文名称,你可以使用choices选项中定义的第二个值,即元组中的第二个元素.你可以通过定义一个serializer,然后在该serializer中使用sourc ...

  2. Vue查询传参

    通过修改 getWK005 函数来实现这一点.这里的 query 参数就是发送 GET 请求时的查询参数.你可以将需要的条件作为 query 对象的属性传递进去.比如,如果你想要按照特定的条件查询信息 ...

  3. 浅析JS构造函数

    构造函数(Constructor Function)是 JavaScript 中创建对象的一种重要方式,它不仅让我们能够创建具有相似属性和方法的对象,还能充分利用 JavaScript 的原型继承机制 ...

  4. Sysbench 使用总结

    Sysbench使用总结 实践环境 CentOS 7.8 Sysbench 1.0.20 下载地址:https://github.com/akopytov/sysbench/archive/refs/ ...

  5. Gradle配置文件解析和使用Meven本地仓库

    Gradle配置文件 使用Gradle创建好项目之后,项目的根目录下会有一个build.gradle文件,该文件就是Gradle的核心配置文件 对应的信息: plugins { id 'java' } ...

  6. SEO自动外链蜘蛛池工具促进百度快速收录怎么样 跟大家详谈一下

    此工具集成市面上所有自动外链网站的资源链接,经过合并.去重.筛选.验证 总结出最终的外链资源 ,软件实时更新 本软件将您繁杂的外链推广转为自动化进行,并且加入站群的支持,您只需要将你的站群域名粘贴到软 ...

  7. 【ELK】Kibana-7.13.1版本 启动报错 Centos6

    报错信息: [root@centos6-1 gcc-4.8.2]# /opt/kibana-7.13.1-linux-x86_64/bin/kibana /opt/kibana-7.13.1-linu ...

  8. 【Java】JDBC Part2 工具类封装实现

    JDBC 工具类封装实现 - 注册和配置都放在静态代码块完成 - 静态方法获取连接,和释放资源 - 本类不产生实例 - 5版本 + 已经可以实现无驱动注册,所以驱动部分注释了 package cn.d ...

  9. 【Windows】开放共享目录

    在项目里面做数据迁移时发现,WindowsServer的多个主机可以进行磁盘共享访问 但是自己设置是灰白无法点击的 文件目录共享还是可以进行设置的 1.找到自己需要共享的目录,右键选择[属性],并找到 ...

  10. 【转载】 【树莓派】为Ubuntu Mate for ARM 更换中国软件源

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/wr132/article/details ...