说一说数据库的并发控制

更新日期: 2019-03-07阅读: 2k标签: 并发

最近在看Elasticsearch时看到了并发控制,由此看到了新的并发控制方式。不得不说Elasticsearch相较于关系型数据库就是两种理论建立的数据存储体系,当然它们在并发控制上也相差甚远,各有千秋。


什么是并发冲突

说到并发就不得不提一下串行,所谓串行就是数据库操作事物按照特定的顺序从上到下执行,在串行操作某个数据表的某个字段的值时写入和读取都很好理解,且不会发生异常。但是往往线上数据操作会发生各种异常,因为线上数据库对用户来说不可能是串行访问的,往往是并发访问。就会产生如写入并发造成的覆盖现象,读写并发造成的脏读现象等。下面简单介绍一下这些异常形成的原因。

A获取字段X的值为3将它减1然后写入数据库X为2,当B在A写入之前同时获取X的值为3将它减1然后写入数据库X为2。
可以看到上面X经过两次减1操作,但是它的值只减了1,因为B将A的操作覆盖了。

如果X的值为1,A想将X的值减1,如果X等于0则返回,当A将减1操作执行完成前,B同样进行这个操作,B取到的X也等于1,然后执行减1操作,会是X的值变为-1。

上面的例子说明了并发操作中存在冲突,需要一种机制来处理这种冲突。于是锁的机制就应运而生来。锁顾名思义就是将需要执行的数据锁起来,从而让他从并发变成串行。


如何治理并发冲突

悲观锁并发控制

悲观锁对数据被修改持悲观态度。即每次获取数据的时候,都会担心数据被修改,所以每次获取数据的时候都会进行加锁,确保在自己使用的过程中数据不会被别人修改,使用完成后进行数据解锁。由于数据进行加锁,期间对该数据进行读写的其他线程都会进行等待。

读写锁

在数据库中,锁被设计为两种模式,即共享锁(读锁)和互斥锁(写锁)。当一个事物获得共享锁之后,它只能进行读操作;当一个事物获取一行数据当互斥锁时,就可以对该行数据进行读和写操作。
多个事物可以同时获取同一行数据的共享锁,但互斥锁同一时间只能被一个事物获取。没有获得锁但事物将处于等待状态。

两阶段锁协议(2PL)

两阶段锁协议是一种能够保证事物可串行化但协议,它将事物的获取锁和释放锁分成增长和缩减两个不同的阶段。在增长阶段,一个事物可以获得锁但是不能释放锁;而在缩减阶段事物只可以释放锁,不能获取新的锁。

  1. Strict 2PL    事物持有的互斥锁必须在提交后再释放
  2. Rigorous 2PL    事物持有的所以锁必须在提交后释放

乐观锁并发控制

乐观锁并不是真正的锁,而是一种并发控制的思想。它可以基于各种协议来实现这种并发控制。不同的事物按照锁协议同一数据项依次执行,因为后面执行的事务想要获取的数据已经被前面的事务加锁,只能等待锁的释放。

基于时间戳的协议

每个事务都有一个全局唯一且随时间递增的时间戳。每一项数据有两个时间戳分别是读时间戳和写时间戳,分别代表事务的开始和结束。这个协议使无论读操作还是写操作都需要比较读写时间戳,如果小于当前值(最后一次操作都时间戳)就会拒绝,然后回滚,然后数据库给这个事务一个新的时间戳重新执行。

基于验证的协议

这个协议根据事务的只读或者更新将所有事务的执行分为两到三个阶段。
在读阶段,数据库会执行事务中的全部读操作和写操作,并将所以写后的值村润临时变量中,并不会真正更新数据库的内容;然后进入下一阶段,数据库会检测当前改动是否合法,即是否有其他事务在读阶段更新了数据,如果通过测试就直接写入数据库,否则就拒绝执行。

多版本并发控制

多版本并发控制意味着更新数据时不覆盖原数据,而是在数据库中保留多个版本,根据需要使用某个版本。它本质上跟上面的不冲突,属于两种解决方案,它并不能解决冲突而是将冲突分割开。


链接: https://fly63.com/article/detial/2330

PHP和Redis实现在高并发下的抢购及秒杀功能示例详解

抢购、秒杀是平常很常见的场景,面试的时候面试官也经常会问到,比如问你淘宝中的抢购秒杀是怎么实现的等等。抢购、秒杀实现很简单,但是有些问题需要解决,主要针对两个问题:

PHP-高并发和大流量的解决方案

在互联网时代,并发,高并发通常是指并发访问。也就是在某个时间点,有多少个访问同时到来。 高并发架构相关概念QPS (每秒查询率) : 每秒钟请求或者查询的数量,在互联网领域,指每秒响应请求数

处理高并发的一般思路

今天看见有人聊目前系统有2亿的PV,该如何优化?当我看到这个话题的时候,突然在想自己工作中也遇到了不少高并发的场景了,所以即兴发挥,在这里简单总结和分享下,欢迎指正和补充。

nodejs使用 eventproxy 控制并发

很多网站有并发连接数的限制,所以当请求发送太快的时候会导致返回值为空或报错。 安装依赖 express superagent cheerio eventproxy。新建app.js 抓取所有的url

PHP 并发场景的几种解决方案

在秒杀,抢购等并发场景下,可能会出现超卖的现象,在PHP语言中并没有原生提供并发的解决方案,因此就需要借助其他方式来实现并发控制。列出常见的解决方案有:

并发编程三要素:原子性,有序性,可见性

并发编程三要素:原子性: 一个不可再被分割的颗粒。原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。有序性: 程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)

通过Iterator控制Promise.all的并发数

异步是 js 一个非常重要的特性,但很多时候,我们不仅仅想让一系列任务并行执行,还想要控制同时执行的并发数,尤其是在针对操作有限资源的异步任务,比如文件句柄,网络端口等等。

nodejs如何解决高并发?

Node可以在不新增额外线程的情况下,依然可以对任务进行并发处理 —— Node.js是单线程的。它通过事件循环(event loop)来实现并发操作,对此,我们应该要充分利用这一点 —— 尽可能的避免阻塞操作

如何利用 JavaScript 实现并发控制

在开发过程中,有时会遇到需要控制任务并发执行数量的需求。例如一个爬虫程序,可以通过限制其并发任务数量来降低请求频率,从而避免由于请求过于频繁被封禁问题的发生。

JavaScript 中如何实现并发控制?

在日常开发过程中,你可能会遇到并发控制的场景,比如控制请求并发数。那么在 JavaScript 中如何实现并发控制呢?在回答这个问题之前,我们来简单介绍一下并发控制。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!