资讯专栏INFORMATION COLUMN

说一说数据库的并发控制

DirtyMind / 1051人阅读

摘要:多个事物可以同时获取同一行数据的共享锁,但互斥锁同一时间只能被一个事物获取。事物持有的互斥锁必须在提交后再释放事物持有的所以锁必须在提交后释放乐观锁并发控制乐观锁并不是真正的锁,而是一种并发控制的思想。

说一说数据库的并发控制

最近在看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)

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

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

Rigorous 2PL    事物持有的所以锁必须在提交后释放



乐观锁并发控制

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

基于时间戳的协议

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

基于验证的协议

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

多版本并发控制

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/48577.html

相关文章

  • 「Python 面试」第五次更新

    摘要:也就是说当使用字符型存储数据后,该数据转换为二进制时的长度超过了位,那么该数据将不会完整存储,会丢失一部分数据。 showImg(https://segmentfault.com/img/bVbuYxg?w=3484&h=2480); 阅读本文大约需要 8 分钟。 写在前面 数据库打算只写 MySQL,Redis 两部分,不会很细,主要以面试题为主。这次写的是 MySQL 篇。 1.说...

    zhunjiee 评论0 收藏0
  • 网易考拉海购Java后台开发实习-面经(已拿offer)

    一面(23min) 自我介绍 项目中最自豪的部分 也没什么太自豪的,就是在移动端开发的时候不存在cookie和session,然后用redis存了一下验证码感觉还不错。 讲一讲ArrayList和LinkedListArrayList底层实现是数组,并且每次扩容扩容1.5倍,常用在查询较多的场景中。而LinkedList底层实现是链表常用在增删比较多的场景 你说你对锁有了解,说一说你最熟...

    Shonim 评论0 收藏0
  • 一说 HTML 中 script 标签

    摘要:元素在页面中使用语言主要的方法就是使用元素,元素内部的代码从上而下依次执行。换句话说的代码可能会先于中的代码执行,所以在使用属性时,要避免两个相互依赖。 我们在 《Javascript简史》这遍文章中说过,「Javascript」这门语言是由 Netscape开发而来,当初开发的时候为了能让 「Javascript」这门语言能与 HTML 页面共存,而且不影响页面的其他内容,为此增加了...

    fox_soyoung 评论0 收藏0
  • 一说 HTML 中 script 标签

    摘要:元素在页面中使用语言主要的方法就是使用元素,元素内部的代码从上而下依次执行。换句话说的代码可能会先于中的代码执行,所以在使用属性时,要避免两个相互依赖。 我们在 《Javascript简史》这遍文章中说过,「Javascript」这门语言是由 Netscape开发而来,当初开发的时候为了能让 「Javascript」这门语言能与 HTML 页面共存,而且不影响页面的其他内容,为此增加了...

    rubyshen 评论0 收藏0
  • 一说 HTML 中 script 标签

    摘要:元素在页面中使用语言主要的方法就是使用元素,元素内部的代码从上而下依次执行。换句话说的代码可能会先于中的代码执行,所以在使用属性时,要避免两个相互依赖。 我们在 《Javascript简史》这遍文章中说过,「Javascript」这门语言是由 Netscape开发而来,当初开发的时候为了能让 「Javascript」这门语言能与 HTML 页面共存,而且不影响页面的其他内容,为此增加了...

    Nekron 评论0 收藏0

发表评论

0条评论

DirtyMind

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<