SQL Server – Concurrency 并发控制
前言
以前写过相关的, 但这篇主要讲一下概念. 帮助理解
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 并发控制的更多相关文章
- 数据库并发控制及SQL Server的并发控制机制
在多用户和网络环境下,数据库是一个共享资源,多个用户或应用程序同时对数据库的同一数据对象进行读写操作,这种现象称为对数据库的并发操作.显然并发操作可以充分利用系统资源,提高系统效率.虽然如此,但是如果 ...
- 第0/24周 SQL Server 性能调优培训引言
大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...
- SQL Server 内存中OLTP内部机制概述(二)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- SQL Server 性能调优培训引言
原文:SQL Server 性能调优培训引言 大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤 ...
- SQL Server 一致性读
我们在Oracle和MySQL数据库中已经对一致性读的概念比较熟悉了,但是在SQL Server中却鲜少提及,但SQL Server自2005版本以来其实也实现了一致性读,几乎所有关系型数据库产品的一 ...
- 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 ...
- Microsoft SQL Server中的事务与并发详解
本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一 ...
- 再谈SQL Server中日志的的作用
简介 之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用.如果您没有看过我之前的文章,请参阅: 浅谈SQL Server ...
- SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- SQL Server 2014新特性探秘(1)-内存数据库
简介 SQL Server 2014提供了众多激动人心的新功能,但其中我想最让人期待的特性之一就要算内存数据库了.去年我再西雅图参加SQL PASS Summit 2012的开幕式时,微软就宣布 ...
随机推荐
- Javascript克隆数据
JS 复制数据 1 浅复制 具体方法 // 数组 Array.prototype.slice // 普通对象 Object.assign 思考 2 深复制 1) function deepClone( ...
- thinkphp模型hasOne、hasMany、belongsTo详解
在ThinkPHP框架中,hasOne.hasMany和belongsTo是用于定义模型间一对多(1:n).一对一(1:1)和多对一(n:1)关联关系的方法.以下是一些简单的示例来解释这些关系: 1. ...
- odoo 给form表单视图内联列表添加按钮
实践环境 Odoo 14.0-20221212 (Community Edition) 代码实现 模块文件组织结构 说明:为了更好的表达本文主题,一些和主题无关的文件.代码已略去 odoo14\cus ...
- Odoo 自定义form表单按钮点击事件处理程序
实践环境 Odoo 14.0-20221212 (Community Edition) 代码实现 方案1 通过研究发现,点击odoo form表单按钮时,会调用odoo14\odoo\addons\w ...
- appium模拟键盘事件
原方法: 1 def press_keycode(self, keycode, metastate=None): 2 """Sends a keycode to the ...
- Megacity Unity Demo工程学习
1.前言 Megacity Demo发布于2019年春,本博文撰写于2024年,ECS也早已Release并发布了1.2.3版本.不过好在核心变化不大,多数接口也只是换了调用名称, 该Demo相较于之 ...
- DASCTF2022.07赋能赛PWN部分WP
DASCTF2022.07赋能赛PWN部分WP eyfor 程序保护情况 64位ida逆向 可以看见是一个随机数的逻辑,只要我们猜不对4次就可以进入漏洞函数,但是我感觉这原本可能是==号,让用随机数的 ...
- 【Android】虚拟设备运行BUG
虚拟设备是AndroidStudio提供的一个真机模拟运行环境 跑这个虚拟设备要下载手机系统镜像才能跑起来 然后项目中勾选这个虚拟设备,怎么设置就不赘述了 问题奇怪的是运行环境有了,App应用程序也能 ...
- Http、Https简介和Session、token的请求流程
Http Http (超文本输出协议) 是一种分布式.协作式和超媒体信息系统的应用层协议,它通常运行在TCP之上,因特网应用最广泛的便是Http协议,所有www都遵循这个标准.主要用于Web 浏览器与 ...
- Accurately computing running variance —— 已知两个数列各自的均值和方差,如何快速求出两个数列拼合后的均值和方差(续)
原内容来自: https://www.johndcook.com/blog/standard_deviation/ 计算公式: 该种计算方式可以只保存历史数据的平方和,与历史数据的和. 相关前文: 已 ...