分布式系统阅读笔记(十六)-----事务和并发控制

介绍

在分布式系统中,事务的运用和共享资源的并发控制是非常常见的。简单的说,事务就是一些原子的操作的集合。原子操作的意思就是要么操作成功要么操作失败,没有其他的选择。并发控制是出现在高并发场景的时候,本篇主要描述3种常见的手段,1、锁的措施。2、乐观并发控制手段。3、时间戳序列方式。在此之前,先回顾一下平时在写程序的时候,常见的用于同步的手段,比如说:

1、用synchronize关键字,这个字java里用的,保证只有一个线程能执行里面的方法。

2、wait()和notify()方法用以协调同步使用的,比如在blockingQueue阻塞队列里时用的。

事务的失败是可以恢复的,通过永久的存储,可以再次恢复,可以通过异地的副本措施。

事务

事务有2个特征:1、操作的独立性,与其他的操作时隔离的,不受影响的。2、他的操作要么执行成功,要么就执行失败,且不会对其他的操作有任何影响。因为事务要求操作的原子性,因此要保证操作的同步,这时候服务器的目标就是提高事务的并发程序又不影响他的原子性。

1、每个事务被一个协调器所创建盒管理的。

2、在事务并发的情况下会出现2个比较的典型的问题:1、失去更新问题。2、状态不一致问题,典型的就是数据读出的是老的数据,而事实上数据已经被更新了。

3、事务从中止的情况下恢复,那么服务器必须记录下所有已提交事务的记录或者为事务留存许多的暂存的版本。

嵌套事务

嵌套事务(Nested transaction)是从单一事务中扩展而来的。他是由一系列的事务组合而成的,分为the top-level transaction和subtransaction 2种事务,subtransction指的是他的子事务。以这2种事务构成了树状的结构。

1、嵌套事务相比较于普通事务的优点:1、支持更多的并发度,他的子事务可以在不同的服务器上并行。2、子事务可以独立的提交或者中止事务。

2、嵌套事务的一些规则:1、一个事务只有等到他的子事务都完成了才能决定提交还是中止。2、当父事务中止时候,所有子事务都将会中止。

锁是一种非常常见的用于控制资源访问并发的措施,我们一般所说的锁是指排他锁,只能独占式的。当然锁可以进行细粒度化的划分。比如说,可以划分为读锁和写锁的分离,读锁其实是大家共享的,也叫共享锁。

1、在嵌套事务中,他的锁模式有一点点的不同,当父事务持有锁的事务,他的子事务可以接过父事务的锁执行操作,执行完毕,再归还锁给父事务。

2、使用锁最讨厌出现的情况就是死锁,简单点说,就是大家都在等对方手中的资源,谁都不肯放手,组后就一直持僵持状态。

3、预防死锁的办法有:1、把事务中所涉及到事务全部进行锁定。这样其他的事务就不会跟你抢占资源了,但是显然这么做,操作的效率大大降低,只会运行单位时间执行一个操作了。2、进行死锁的监测,通过发现有没有循环的等待图。3、超时的检测也是一种常用的检测,但是这个时间间隔的设定是一个大的问题,因为中间有很多的影响因素。

4、不同的锁模式可以增加并发度。这里提及2种锁模式:1、Two-version Locking,2版本锁,用到了3种锁,read lock,write lock,和commit lock。2、hierarchic locks,分层级的锁模式。

乐观并发控制

上面说的锁是一种悲观的并发控制手段,而这节说的则是一种乐观的并发控制手段,完全不同的方式。先列举几个锁方式的缺点:

1、不支持对数据的高并发的访问,这期间一般都有Delay的。

2、会造成死锁,这个问题一直很大。

3、如果出现随机的失败,那么锁将得不到释放,让等待该锁的对象会陷入无限的等待。

而这里我们说的乐观并发控制的原理就是通过观察。高并发的情况不就是怕有冲突吗,没事,我们解决就是了。

1、在乐观并发控制的时候,有3个阶段:1、working phase工作阶段,在这个阶段会有一个对象的多个临时的版本。2、validation phase 验证阶段,就是解决第一阶段的有冲突矛盾的地方。3、update phase 更新阶段,伴随的是事务的提交。

2、验证阶段的方式有2种:1、backward validation ,向后验证。2、forward validation ,向前验证。

时间戳序列

在并发控制的模式中时间戳的方式是基于时间戳的序列。每个操作每个事务会为其他分配一个独立,唯一的时间戳值。每个时间戳的值代表了一个操作的对象的版本。与上一个思想有些类似。核心思想是通过读写事务的时间戳的值,来比较先后顺序,在一定规则的判断下,最后决定是否执行操作。比如你写事务的时间戳的值必须要大于最后一个读事务的时间戳值,这样表明已经没人在读此对象了,你才可以进行操作。

参考文献:<<Distributed Sysytems Concepts And Design>>原版第五版,author:George Coulouris,Jean Dollimore, Tim Kindberg,Gordon Blair

时间: 2024-10-06 02:30:27

分布式系统阅读笔记(十六)-----事务和并发控制的相关文章

分布式系统阅读笔记(六)-----间接通信

介绍) 这次的内容其实与上篇学习的内容正好是相对的,之前的各种通讯方式其实说的都是直接通讯,而这次我学习的内容是间接通讯,二者的本质区别在于间接通讯把时间和空间进行了分离,直接通讯在这2点上都进行了耦合,有点事操作直接简单,但是缺点也是非常明显的,扩展性差,不能很好的面对变化.根据空间和时间2个维点,可以有4种不同的类型的通信方式,时间的分离是这样的形式:消息的本质在传送的过程中有一定的生存时间,并不要求一定要实时的去接受.空间的分离是这样的形式:消息的发送不需要去知道接受者是谁,就是说无须知道

Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable

酒,是个好东西,前提要适量.今天参加了公司的年会,主题就是吃.喝.吹,除了那些天生话唠外,大部分人需要加点酒来作催化剂,让一个平时沉默寡言的码农也能成为一个喷子!在大家推杯换盏之际,难免一些画面浮现脑海,有郁闷抓狂的,有出成果喜极而涕的,有不知前途在哪儿的迷茫与不安……总的来说,近一年来,不白活,不虚度,感触良多,不是一言两语能说得清道的明的,有时间可以做个总结,下面还是言归正传谈技术吧. 上篇在了解了Hadoop的目录和源码结构后,说好的要啃源码的,那就得啃.也感谢一直以来关注我.支持我的网友

swift 笔记 (十六) —— 可选链

可选链(Optional Chaining) 我们都知道"可选型"是什么,那么可选链又是什么,举个例子解释一下: struct MyName{ var name } struct MyInfo { var myName:MyName? = MyName() } class MyClass { var structInstance: MyInfo? = MyInfo() } 这里有两个结构体和一个类,当,这个类实例化的时候: var myInstance = MyClass() 所有的可

构建之法阅读笔记05-第六章

阅读笔记 第六章:敏捷流程 第六章敏捷流程主要介绍了什么是敏捷流程及其原则,还有什么时候可以选择敏捷的开发方法,什么时候选择其他方法. 敏捷的流程是指一系列价值观和方法论的集合.介绍了一些敏捷开发原则,比如,经常发布可用的软件,业务人员和开发人员在项目开发过程中应该每天共同工作,面对面的交流始终是最有效的沟通方式,不断关注技术和设计,保持简明,团队要学会自我管理,时时总结如何提高团队效率,并付诸行动. 敏捷流程的方法论---Scrum方法论.首先第一步需要找出完成产品需要做的事情,然后决定当前的

面对软件错误构建可靠的分布式系统(阅读笔记)

阅读笔记 joe Armstrong 段先德 译 核心问题:如何在存在软件错误的情况下编写具有合理行为的软件 ,如何避免像死锁.死循环等问题 ERLANG的世界观,一切皆进程.将任务分离成层次化的一系列任务,强隔离的进程负责来执行每个具体化的任务,进程之间不共享状态(实际上ETS跨越了这个准则). 只能通过消息传递来通信,必须注意进程消息的堵塞问题 工作者和监督者构成一个完整的系统,监督者的作用就是监控整个系统的运行状况.并对突发情况进行可靠的处理. behaviour库的设计思想就是将程序的并

C++学习笔记十六-模板和泛型编程(二)

C++学习笔记十六-模板和泛型编程(二) 16.4 类模板成员 1.模板作用域中模板类型的引用: 通常,当使用类模板的名字的时候,必须指定模板形参.这一规则有个例外:在类本身的作用域内部,可以使用类模板的非限定名.例如,在默认构造函数和复制构造函数的声明中,名字 Queue 是 Queue<Type> 缩写表示.实质上,编译器推断,当我们引用类的名字时,引用的是同一版本.因此,复制构造函数定义其实等价于: Queue<Type>(const Queue<Type> &a

《构建之法》阅读笔记(六)

阅读第八章所得: 第八章是关于需求分析的.原来我是知道做软件之前得知道要做什么,是有一定的复杂性的,但没想到是这么有规则的一部分.对软件的需求也是多种多样的,以后到社会上的时候,有可能顾客并不知道他想要做什么样的软件,如果好好学了这本书,就会有一定的步骤和方法,傍敲侧击.我们会认为团队进行项目的时候开一个会是合理的,但如果要空出一天的时间来讨论这个项目的难处或者各人的感受的话,是十分不合理的.获取软件的需求有很多方法,这十分重要.比如,书中提到的一位父亲就比较喜欢用新浪网来看新闻,大多数人偏爱h

深入理解 C 指针阅读笔记 -- 第六章

Chapter6.h #ifndef __CHAPTER_6_ #define __CHAPTER_6_ /*<深入理解C指针>学习笔记 -- 第六章*/ typedef struct __person { char* name; char* title; unsigned int age; }person; /*结构体内存的释放问题*/ void __struct_memory_test(); #endif Chapter6.cpp #include "Chapter6.h&quo

MYSQL进阶学习笔记十六:MySQL 监控!(视频序号:进阶_35)

知识点十六:MySQL监控(35) 一.为什么使用MySQL监控 随着软件后期的不断升级,myssql的服务器数量越来越多,软硬件故障的发生概率也越来越高.这个时候就需要一套监控系统,当主机发生异常时,此时通过监控系统发现和处理. 这个监控实际上是在我们的开发完成之后,这个时候软件就开始在运行,这个运行我们就需要去关注到mysql服务器是否正常,那么我们要观察它就需要给它提供一些监控,这监控就是当它发生故障之后, 那么我们这个监控就会告诉我们到底什么地方发生了一些异常或者一些错误,这个时候我们就