×

分布式数据库两阶段提交协议

分布式数据库两阶段提交协议(分布式存储中,怎样使用paxos算法保证数据的一致性)

admin admin 发表于2023-09-24 13:53:12 浏览38 评论0

抢沙发发表评论

本文目录

分布式存储中,怎样使用paxos算法保证数据的一致性

在分布式系统中,我们经常遇到多数据副本保持一致的问题,在我们所能找到的资料中该问题讲的很笼统,模模糊糊的,把多个问题或分类糅合在一起,难以理解。在思考和翻阅资料后,通俗地把一致性的问题可分解为2个问题:1、任何一次修改保证数据一致性。2、多次数据修改的一致性。在弱一致性的算法,不要求每次修改的内容在修改后多副本的内容是一致的,对问题1的解决比较宽松,更多解决问题2,该类算法追求每次修改的高度并发性,减少多副本之间修改的关联性,以获得更好的并发性能。例如最终一致性,无所谓每次用户修改后的多副本的一致性及格过,只要求在单调的时间方向上,数据最终保持一致,如此获得了修改极大的并发性能。在强一致性的算法中,强调单次修改后结果的一致,需要保证了对问题1和问题2要求的实现,牺牲了并发性能。本文是讨论对解决问题1实现算法,这些算法往往在强一致性要求的应用中使用。解决问题1的方法,通常有两阶段提交算法、采用分布式锁服务和采用乐观锁原理实现的同步方式,下面分别介绍这几种算法的实现原理。两阶段提交算法在两阶段提交协议中,系统一般包含两类机器(或节点):一类为协调者(coordinator),通常一个系统中只有一个;另一类为事务参与者(participants,cohorts或workers),一般包含多个,在数据存储系统中可以理解为数据副本的个数。两阶段提交协议由两个阶段组成,在正常的执行下,这两个阶段的执行过程如下所述:阶段1:请求阶段(commit-request phase,或称表决阶段,voting phase)。 在请求阶段,协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。阶段2:提交阶段(commit phase)。 在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行响应的操作。 举个例子:A组织B、C和D三个人去爬长城:如果所有人都同意去爬长城,那么活动将举行;如果有一人不同意去爬长城,那么活动将取消。用2PC算法解决该问题的过程如下:首先A将成为该活动的协调者,B、C和D将成为该活动的参与者。阶段1:A发邮件给B、C和D,提出下周三去爬山,问是否同意。那么此时A需要等待B、C和D的邮件。B、C和D分别查看自己的日程安排表。B、C发现自己在当日没有活动安排,则发邮件告诉A它们同意下周三去爬长城。由于某种原因,D白天没有查看邮件。那么此时A、B和C均需要等待。到晚上的时候,D发现了A的邮件,然后查看日程安排,发现周三当天已经有别的安排,那么D回复A说活动取消吧。阶段2:此时A收到了所有活动参与者的邮件,并且A发现D下周三不能去爬山。那么A将发邮件通知B、C和D,下周三爬长城活动取消。此时B、C回复A“太可惜了”,D回复A“不好意思”。至此该事务终止。两阶段提交算法在分布式系统结合,可实现单用户对文件(对象)多个副本的修改,多副本数据的同步。其结合的原理如下: 1、客户端(协调者)向所有的数据副本的存储主机(参与者)发送:修改具体的文件名、偏移量、数据和长度信息,请求修改数据,该消息是1阶段的请求消息。2、存储主机接收到请求后,备份修改前的数据以备回滚,修改文件数据后,向客户端回应修改成功的消息。 如果存储主机由于某些原因(磁盘损坏、空间不足等)不能修改数据,回应修改失败的消息。3、客户端接收发送出去的每一个消息回应,如果存储主机全部回应都修改成功,向每存储主机发送确认修改的提交消息;如果存在存储主机回应修改失败,或者超时未回应,客户端向所有存储主机发送取消修改的提交消息。该消息是2阶段的提交消息。4、存储主机接收到客户端的提交消息,如果是确认修改,则直接回应该提交OK消息;如果是取消修改,则将修改数据还原为修改前,然后回应取消修改OK的消息。5、 客户端接收全部存储主机的回应,整个操作成功。 在该过程中可能存在通信失败,例如网络中断、主机宕机等诸多的原因,对于未在算法中定义的其它异常,都认为是提交失败,都需要回滚,这是该算法基于确定的通信回复实现的,在参与者的确定回复(无论是回复失败还是回复成功)之上执行逻辑处理,符合确定性的条件当然能够获得确定性的结果哲学原理。分布式锁服务 分布式锁是对数据被外界修改持保守态度,在整个数据处理过程中将数据处于锁定状态,在用户修改数据的同时,其它用户不允许修改。 采用分布式锁服务实现数据一致性,是在操作目标之前先获取操作许可,然后再执行操作,如果其他用户同时尝试操作该目标将被阻止,直到前一个用户释放许可后,其他用户才能够操作目标。分析这个过程,如果只有一个用户操作目标,没有多个用户并发冲突,也申请了操作许可,造成了由于申请操作许可所带来的资源使用消耗,浪费网络通信和增加了延时。 采用分布式锁实现多副本内容修改的一致性问题, 选择控制内容颗粒度实现申请锁服务。例如我们要保证一个文件的多个副本修改一致, 可以对整个文件修改设置一把锁,修改时申请锁,修改这个文件的多个副本,确保多个副本修改的一致,修改完成后释放锁;也可以对文件分段,或者是文件中的单个字节设置锁, 实现更细颗粒度的锁操作,减少冲突。常用的锁实现算法有Lamport bakery algorithm (俗称面包店算法), 还有Paxos算法。下面对其原理做简单概述。Lamport面包店算法是解决多个线程并发访问一个共享的单用户资源的互斥问题的算法。 由Leslie Lamport(英语:Leslie Lamport)发明。 Lamport把这个并发控制算法可以非常直观地类比为顾客去面包店采购。面包店只能接待一位顾客的采购。已知有n位顾客要进入面包店采购,安排他们按照次序在前台登记一个签到号码。该签到号码逐次加1。根据签到号码的由小到大的顺序依次入店购货。完成购买的顾客在前台把其签到号码归0. 如果完成购买的顾客要再次进店购买,就必须重新排队。 这个类比中的顾客就相当于线程,而入店购货就是进入临界区独占访问该共享资源。由于计算机实现的特点,存在两个线程获得相同的签到号码的情况,这是因为两个线程几乎同时申请排队的签到号码,读取已经发出去的签到号码情况,这两个线程读到的数据是完全一样的,然后各自在读到的数据上找到最大值,再加1作为自己的排队签到号码。为此,该算法规定如果两个线程的排队签到号码相等,则线程id号较小的具有优先权。把该算法原理与分布式系统相结合,即可实现分步锁。Paxos算法该算法比较热门,参见WIKI,

分布式事务的概念

为了实现分布式事务,需要使用下面将介绍的两阶段提交协议。 * 阶段一:开始向事务涉及到的全部资源发送提交前信息。此时,事务涉及到的资源还有最后一次机会来异常结束事务。如果任意一个资源决定异常结束事务,则整个事务取消,不会进行资源的更新。否则,事务将正常执行,除非发生灾难性的失败。为了防止会发生灾难性的失败,所有资源的更新都会写入到日志中。这些日志是永久性的,因此,这些日志会幸免遇难并且在失败之后可以重新对所有资源进行更新。 * 阶段二:只在阶段一没有异常结束的时候才会发生。此时,所有能被定位和单独控制的资源管理器都将开始执行真正的数据更新。 在分布式事务两阶段提交协议中,有一个主事务管理器负责充当分布式事务协调器的角色。事务协调器负责整个事务并使之与网络中的其他事务管理器协同工作。 为了实现分布式事务,必须使用一种协议在分布式事务的各个参与者之间传递事务上下文信息,IIOP便是这种协议。这就要求不同开发商开发的事务参与者必须支持一种标准协议,才能实现分布式的事务。

解析:怎样理解分布处理和分布式数据库

一个分布式数据库在用户面前为单个逻辑数据库,但实际上是由存储在多台计算机上的一组数据库组成。在几台计算机 上的数据库通过网络可同时修改和存取,每一数据库受它的局部的DBMS控制。分布式数据库中每一个数据库服务器合作地维护全局数据库的一致性。 在系统中的每一台计算机称为结点。如果一结点具有管理数据库 软件,该结点称为数据库服务器。如果一个结点为请求服务器的信息的一应用,该结点称为客户。在ORACLE客户,执行数据库应用,可存取数据信息和与用户交互。在服务器,执行ORACLE软件,处理对ORACLE数据库并发、共享数据存取。ORACLE允许上述两部分在同一台计算机上,但当客户部分和服务器部分是由网连接的不同计算机上时,更有效。 分布处理是由多台处理机分担单个任务的处理。在ORACLE数据库系统中分布处理的例子如: 客户和服务器是位于网络连接的不同计算机上。 单台计算机上有多个处理器,不同处理器分别执行客户应用。 SQL*NET是ORACLE网络接口,允许运行在网络工作站的ORACLE工具和服务器上,可存取、修改、共享和存储在其它服务器上的数据。SAQL*NET可被认为是网络通信的程序接口。SQL*NET利用通信协议和应用程序接口(API)为OARCLE提供一个分布式数据库和分布处理。 SQL*NET驱动器为在数据库服务器上运行的ORACLE进程与ORACLE工具的用户进程之间提供一个接口。 参与分布式数据库的每一服务器是分别地独立地管理数据库,好 像每一数据库不是网络化的数据库。每一个数据库独立地被管理,称为场地自治性。场地自治性有下列好处: ◆系统的结点可反映公司的逻辑组织。 ◆由局部数据库管理员控制局部数据,这样每一个数据库管理员责任域要 小一些,可更好管理。 ◆只要一个数据库和网络是可用,那么全局数据库可部分可用。不会因一个数据库的故 障而停止全部操作或引起性能瓶颈。 ◆故障恢复通常在单个结点上进行。 ◆每个局部数据库存在一个数据字典。 ◆结点可独立地升级软件。 可从分布式数据库的所有结点存取模式对象,因此正像非分布的局部的DBMS,必须提供一种机制,可在局部数据库中引用一个对象。分布式DBMS必须提供一种命名模式,以致分布式数据库中一个对象可在应用中唯一标识和引用。一般彩在层次结构的每一层实施唯一性。分布式DVMS简单地扩充层次命名模型,实施在网络上唯一数据库命名。因此一个对象的全局对象名保证在分布式数据库内是唯一。 ORACLE允许在SQL语句中使用佤对象名引用分布式数据库中的模式对象(表、视图和过程)。在ORACLE中,一个模式对象的全局名由三部分组成:包含对象的模式名、对象名、数据库名、其形式如: SCOTT.EMP@SALES.DIVISION3.ACME.COM 其中SCOTT为模式名,EMP为表名,@符号之后为数据库名. 一个远程查询为一查询,是从一个或多个远程表中选择信息,这些表驻留在同一个远程结点. 一个分布式查询可从两个或多个结点检索数据.一个分布式更新可修改两个或两个以上结点的数据. 一个远程事务为一个事务,包含一人或多个远程语句,它所引用的全部是在同一个远程结点上.一个分布式事务中一个事务,包含一个或多个语句修改分布式数据库的两个或多个不同结点的数据. 在分布式数据库中,事务控制必须在网络上直辖市,保证数据一致性.两阶段提交机制保证参与分布式事务的全部数据库服务器是全部提交或全部回滚事务中的语句. ORACLE分布式数据库系统结构可由ORACLE数据库管理员为终端用户和应用提供位置透明性,利用视图、同义词、过程可提供ORACLE分布式数据库系统中的位置透明性. ORACLE允许在SELECT(查询)、INSERT、UPDATE、DELETE、SELECT…FOR UPDATE和LOCK TABLE语句中引用远程数据。对于查询,包含有连接、聚合、子查询和SELECT …FOR UPDATE,可引用本地的、远程的表和视图。对于UPDATE、INSERT、DELETE和LOCK TABLE语句可引用本地的和远程的表。注意在引用LONG和LONG RAW列、序列、修改表和封锁表时,必须位于同一个结点。ORACLE不允许作远程DDL语句。 在单场地或分布式数据库中,所有事务都是用COMMIT或ROLLBACK语句中止。ORACLE提供两种机制实现分布式数据库中表重复的透明性:表快照提供异步的表重复;触发器实现同步的表的重复。在两种情况下,都实现了对表重复的透明性。

什么是分布式事务的两阶段提交

  XA是由X/Open组织提出的分布式事务的规范。XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接口。XA接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁。XA之所以需要引入事务管理器是因为,在分布式系统中,从理论上讲(参考Fischer等的论文),两台机器理论上无法达到一致的状态,需要引入一个单点进行协调。事务管理器控制着全局事务,管理事务生命周期,并协调资源。资源管理器负责控制和管理实际资源(如数据库或JMS队列)。下图说明了事务管理器、资源管理器,与应用程序之间的关系:  图1.XA规范下的分布式事务各类参与者之间的关系  2.JTA  作为java平台上事务规范JTA(Java Transaction API)也定义了对XA事务的支持,实际上,JTA是基于XA架构上建模的,在JTA 中,事务管理器抽象为javax.transaction.TransactionManager接口,并通过底层事务服务(即JTS)实现。像很多其他的java规范一样,JTA仅仅定义了接口,具体的实现则是由供应商(如J2EE厂商)负责提供,目前JTA的实现主要由以下几种:  1.J2EE容器所提供的JTA实现(JBoss)  2.独立的JTA实现:如JOTM,Atomikos.这些实现可以应用在那些不使用J2EE应用服务器的环境里用以提供分布事事务保证。如Tomcat,Jetty以及普通的java应用。  3.两阶段提交  所有关于分布式事务的介绍中都必然会讲到两阶段提交,因为它是实现XA分布式事务的关键(确切地说:两阶段提交主要保证了分布式事务的原子性:即所有结点要么全做要么全不做)。所谓的两个阶段是指:第一阶段:准备阶段和第二阶段:提交阶段。  图2.两阶段提交示意图(摘自info发布的《java事务设计策略》一文)  1.准备阶段:事务协调者(事务管理器)给每个参与者(资源管理器)发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,写本地的redo和undo日志,但不提交,到达一种“万事俱备,只欠东风”的状态。(关于每一个参与者在准备阶段具体做了什么目前我还没有参考到确切的资料,但是有一点非常确定:参与者在准备阶段完成了几乎所有正式提交的动作,有的材料上说是进行了“试探性的提交”,只保留了最后一步耗时非常短暂的正式提交操作给第二阶段执行。)  2.提交阶段:如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)  将提交分成两阶段进行的目的很明确,就是尽可能晚地提交事务,让事务在提交前尽可能地完成所有能完成的工作,这样,最后的提交阶段将是一个耗时极短的微小操作,这种操作在一个分布式系统中失败的概率是非常小的,也就是所谓的“网络通讯危险期”非常的短暂,这是两阶段提交确保分布式事务原子性的关键所在。(唯一理论上两阶段提交出现问题的情况是当协调者发出提交指令后当机并出现磁盘故障等永久性错误,导致事务不可追踪和恢复)  从两阶段提交的工作方式来看,很显然,在提交事务的过程中需要在多个节点之间进行协调,而各节点对锁资源的释放必须等到事务最终提交时,这样,比起一阶段提交,两阶段提交在执行同样的事务时会消耗更多时间。事务执行时间的延长意味着锁资源发生冲突的概率增加,当事务的并发量达到一定数量的时候,就会出现大量事务积压甚至出现死锁,系统性能就会严重下滑。这就是使用XA事务  4.一阶段提交(Best Efforts 1PC模式)  不像两阶段提交那样复杂,一阶段提交非常直白,就是从应用程序向数据库发出提交请求到数据库完成提交或回滚之后将结果返回给应用程序的过程。一阶段提交不需要“协调者”角色,各结点之间不存在协调操作,因此其事务执行时间比两阶段提交要短,但是提交的“危险期”是每一个事务的实际提交时间,相比于两阶段提交,一阶段提交出现在“不一致”的概率就变大了。但是我们必须注意到:只有当基础设施出现问题的时候(如网络中断,当机等),一阶段提交才可能会出现“不一致”的情况,相比它的性能优势,很多团队都会选择这一方案。关于在spring环境下如何实现一阶段提交,有一篇非常优秀的文章值得参考:

什么是分布式事务处理

美 国Sybase 公 司 于 今 年 七 月 发 布 了PowerBuilder 6.0 的Beta 版, 正 式 的 版 本也 将 于 不 久 的 将 来 推 出, 其 中 对 分 布 式 事 务 处 理 的 支持 是 新 版 本 中 增 强 得 最 多 的 功 能。 早 在1995 年,PowerSoft 公司 就 提 出 了 在“ 分 布 式 事 务” 方 面 的 发 展 战 略, 并 在1996 年 发 布 的PowerBuilder 5.0 中 支 持 了 分 布 式 事 务 处 理 的 功 能,笔 者 在 以 前 的 讲 座 中 也 曾 经 讨 论 过 有 关 如 何 创 建 分布 式PowerBuilder 应 用 的 问 题, 但 是 得 到 读 者 反 馈 意 见 却 很少。 以 往, 一 个 使 用PowerBuilder 开 发 客 户/ 服 务 器 应 用 软 件的 程 序 员 是 较 少 会 想 到 使 用 分 布 式 事 务 来 分 割 应 用的, 因 此 一 般 的 用 户 对 分 布 式 事 务 的 概 念 和 意 义 也 不甚 了 解, 这 里 我 们 来 进 一 步 讨 论 一 下 分 布 式 事 务 处 理及 其 应 用。 三 级 体 系 结 构 首 先我 们 介 绍 三 级 体 系 结 构 这 一 概 念。 所 谓 级 是 指 一 种 功能 划 分, 我 们 以 往 所 开 发 的 数 据 库 应 用 软 件 一 般 是 基于 客 户/ 服 务 器 结 构 的, 我 们 称 之 为 两 级 体 系 结 构。 也就 是 说 整 个 系 统 可 以 分 成 两 个 功 能 块, 第 一 级 包 括 了软 件 的 应 用 层 和 表 现 层, 驻 留 于 客 户 端。 我 们 使 用PowerBuilder 开 发 出 的 应 用 主 要 用 于 第 一 级, 运 行 于 客 户 端。 第 二级 包 含 数 据 库 和 服 务 器 的 组 件。 一 个 基 于SQL 的 数 据 库管 理 系 统 一 般 安 装 在 服 务 器 端, 应 用 软 件 在 服 务 器 端进 行 的 操 作 主 要 是 数 据 存 储 和 检 索。 在 两 级 模 式 中 会有 一 些 应 用 逻 辑 以 存 储 过 程 和 触 发 器 的 形 式 存 储 在服 务 器 端, 以 优 化 服 务 器 的 性 能, 但 绝 大 多 数 的 应 用逻 辑 是 放 在 客 户 端 的。 三 级模 式 是 将 系 统 分 为 有 三 个 不 同 的“ 级”: 表 现 级, 商业 逻 辑 级 和 数 据 访 问 级。 表 现 级 是 处 理 用 户 界 面 的 功能; 数 据 访 问 级 是 数 据 源, 在 通 常 状 况 下 指 数 据 库;商 业 逻 辑 级 是 新 增 加 的 一 级, 指 程 序 中 作 出 智 能 决 策的 那 一 部 分 功 能。 在 早 期 的 应 用 中, 这 一 部 分 的 功 能并 不 十 分 复 杂, 一 般 将 其 放 在 表 现 级 即 可, 另 有 少 量以 存 储 过 程 或 触 发 器 的 形 式 放 在 数 据 访 问 一 级, 而 随着 软 件 工 程 的 发 展, 软 件 的 日 益 复 杂, 软 件 中 功 能 增加 最 多 的 就 是 在 这 一 级。 一 个MIS 系 统 的 功 能 由 早 先 的对 某 一 个 表 的 简 单 查 询, 发 展 到 涉 及 多 个 表 的 分 类 统计 求 和, 根 据 复 杂 的 公 式 分 析 计 算, 进 行 决 策 支 持等, 如 将 这 些 增 强 的 功 能 仍 全 部 放 置 在 表 现 级, 会 使得 客 户 机 越 来 越 不 堪 重 负, 因 此 就 有 人 提 出 在 系 统 中将 商 业 逻 辑 分 离 出 来, 单 独 形 成 了 一 级, 这 就 形 成 了三 级 结 构。 随 着 三 级 结 构 的 进 一 步 发 展, 一 般 总 是 把运 行 在 商 业 逻 辑 级 的 软 件 编 写 成 为 了 一 个 为 客 户 机所 调 用, 能 够 完 成 一 定 的 逻 辑 功 能 的 专 用 软 件, 同 数据 库 服 务 器 相 区 别, 我 们 称 之 为 应 用 服 务 器。 在 一 个网 络 中, 可 以 有 着 多 个 不 同 功 能 的 应 用 服 务 器, 为 客户 机 或 其 它 的 应 用 服 务 器 提 供 专 业 服 务, 这 样, 三 级结 构 就 发 展 成 为 了N 级, 这 就 是 所 谓 的 分 布 式 计 算 方式。 分 布式 计 算 的 优 势: 采 用 分 布 式 计 算 有 着 多方 面 的 技 术 优 势, 包 括: 逻 辑封 装 性: 这 是 分 布 式 模 式 中 最 具 诱 惑 力 的 特 征, 这 种模 式 的 根 基 在 于 将 以 往 全 部 由 客 户 机 完 成 的 事 务 逻辑 中 的 一 部 分 从 客 户 端 分 开。 当 使 公 司 需 要 动 态 改 变一 个 应 用 软 件 的 商 业 逻 辑 规 则 时, 只 要 改 变 一 个 应 用服 务 器 的 程 序 即 可, 而 不 需 要 更 改 客 户 端 用 户 界 面,这 样 就 无 需 中 断 用 户, 为 最 终 用 户 重 新 发 放 新 的 界 面软 件 或 亲 自 上 门 为 其 安 装 调 试 并 重 新 培 训 用 户, 提 高了 工 作 效 率。 这 种 多 级 模 式 对 于 需 经 常、 快 速 改 变 应用 程 序 的 行 业 很 有 帮 助。 瘦 客 户 机: 这 种 类 型 的 应 用在 运 行 时 最 显 著 的 特 点 就 是 减 少 甚 至 消 除 了 传 统 的两 级 体 系 结 构 中, 以 客 户 机 为 中 心 或 称 为“ 肥 客 户” 的 模 式, 减 轻 了 客 户 机 的 功 能 负 担, 使 其 消 肿 成 为了“ 瘦 客 户”。“ 肥 客 户” 是 用 户 感 到 十 分 苦 恼 的 事情, 用 户 为 使 用 更 强 功 能 的 软 件, 就 必 须 付 出 高 昂 的维 护 费 用, 不 断 地 为 个 人 电 脑 的 软 硬 件 设 备 升 级。 近日 流 行 的NC 也 正 是 看 到 一 般 用 户 在 维 护PC 机 运 行 时 负担 过 重, 而 提 出 通 过 网 络 将 一 部 分 的 任 务 交 给 了 服 务器 完 成。 这 两 种 方 法 有 着 相 通 之 处。 性能: 性 能 的 提 高 是 三 级 模 式 最 终 被 用 户 采 用 的 主 要 原因。 将 复 杂 的 应 用 和 商 业 逻 辑 分 离 出 来 由 专 门 的 一 台应 用 服 务 器 来 处 理, 既 可 以 提 高 应 用 的 执 行 速 度, 也可 以 减 少 网 络 调 用 的 通 讯 量。 不 过 这 种 性 能 提 高 是 有一 定 代 价 的。 这 就 是 开 发 时 要 将 应 用 逻 辑 分 割 为 客 户端 逻 辑 和 服 务 器 端 逻 辑, 这 就 增 加 了 设 计 的 复 杂 性。 安 全性 管 理: 在 分 布 式 计 算 模 式 中, 由 于 所 有 的 商 业 逻 辑都 驻 留 在 服 务 器 端, 信 息 管 理 部 门 就 可 以 十 分 方 便 地监 控 服 务 器 的 运 行 情 况, 很 容 易 地 控 制 访 问 服 务 器 以及 与 服 务 器 应 用 打 交 道 人 员 的 数 量。 这 可 以 大 大 简 化管 理 员 对 系 统 的 管 理, 减 轻 系 统 维 护 的 工 作 量, 并 确保 系 统 的 可 靠 运 行。 分 布式 事 务 处 理 最 广 泛 和 最 成 功 的 应 用 当 数Internet/Intranet 技术 了, 尽 管 许 多 人 并 不 意 识 到Internet 就 是 一 个 三 级 体 系结 构 的 代 表。 随 着Internet/Intranet 使 用 的 不 断 深 化, 用 户 对Web 服 务 器 所 查 询 的 信 息 就 不 只 局 限 于 以 文 件 方 式 存 放在 服 务 器 端 的 静 态 的 超 文 本 文 件 了。 这 时 我 们 需 要 借助 关 系 型 数 据 库 来 存 放 变 化 的 数 据, 并 在Web 服 务 器 与数 据 库 服 务 器 之 间 以JDBC、CGI 等 协 议 建 立 起 两 者 的 连接, 使Web 服 务 器 能 够 实 现 对 数 据 库 的 即 席 查 询, 并 将结 果 返 回 浏 览 器。 我 们 可 以 发 现, 在 这 样 一 个Intranet 结构 中, 浏 览 器--Web 服 务 器-- 数 据 库 服 务 器 就 分 别 对 应 于客 户 端-- 应 用 服 务 器-- 数 据 库 服 务 器 三 级 体 系 结 构 中的 三 个 环 节,Intranet 就 是 一 个 典 型 的 三 级 体 系 结 构 的 应用。 因 此, 我 们 可 以 认 为,Internet 模 式 的 技 术 优 势 如 用户 界 面 简 单, 管 理 人 员 易 于 维 护 等 也 正 是 多 级 计 算 方式 的 优 势 所 在。 此 外, 由 于PowerBuilder 支 持 分 布 式 事 务 处理, 这 就 使 得PowerBuilder 很 容 易 地 支 持 了 作 为 分 布 式 事 务的 特 例---Internet 的 开 发 了。 分 布 式 应 用 的 开 发 尽 管分 布 式 计 算 是 一 个 较 新 的 概 念, 但 是 使 用PowerBuilder 开 发分 布 式 应 用 却 十 分 简 单, 只 要 您 会 使 用PowerBuilder 中 的 用户 自 定 义 的 不 可 视 对 象, 您 就 会 很 快 地 掌 握 分 布 式PowerBuilder 的 开 发。 在PowerBuilder 中, 应 用 服 务 器 一 端 的 功 能 都 是 通过 不 可 视 用 户 对 象 实 现 的, 开 发 人 员 可 以 将PowerBuilder 的自 定 义 用 户 的 对 象 放 于 应 用 服 务 器 一 侧, 被 称 作 远 端对 象, 在 客 户 端 放 置 该 用 户 对 象 的 代 理 对 象。 此 外,在 服 务 器 一 侧 有 一 个 新 的transport 对 象 用 于 监 听 任 何 一个 用 户 或 其 它 应 用 服 务 器 的 请 求, 在 客 户 端 有 一 个connection 对 象 用 以 建 立 同 远 端 对 象 的 连 接。 客 户 端 的 应 用 程 序通 过connection 对 象 连 接 应 用 服 务 器, 连 接 建 立 后, 客 户端 的 应 用 就 可 以 象 调 用 本 地 对 象 一 样 调 用 应 用 服 务器 上 的 对 象 函 数 了。 当 然, 我 们 这 里 指 的 用 户 可 以 是一 般 意 义 上 的 客 户, 也 可 以 指 应 用 服 务 器 以 一 个 客 户的 身 份 调 用 其 它 应 用 服 务 器。 远 端的 用 户 对 象 中 的 商 业 逻 辑 可 以 是 采 用PowerScript 编 写 的,作 为 一 个 不 可 视 用 户 对 象 的 特 例, 这 个 对 象 可 以 调 用任 何 函 数 或 使 用 数 据 库 命 令, 它 也 可 以 使 用 不 可 视 的DataStore 来 封 装 数 据 库 访 问,PowerBuilder 5.0 可 以 支 持 除 可 视 对 象 以外 的 所 有 的 数 据 类 型。 在 客 户 端 使 用 这 种 形 式 调 用 就象 在 使 用 存 储 过 程 一 样 将 参 数 通 过 网 络 传 递 给 服 务器, 服 务 器 的 运 行 结 果 返 回 客 户 端。

如何用消息系统避免分布式事务

本质上问题可以抽象为:当一个表数据更新后,怎么保证另一个表的数据也必须要更新成功。1 本地事务还是以支付宝转账余额宝为例,假设有支付宝账户表:A(id,userId,amount)余额宝账户表:B(id,userId,amount)用户的userId=1;从支付宝转账1万块钱到余额宝的动作分为两步:1)支付宝表扣除1万:update A set amount=amount-10000 where userId=1;2)余额宝表增加1万:update B set amount=amount+10000 where userId=1;如何确保支付宝余额宝收支平衡呢?有人说这个很简单嘛,可以用事务解决。Begin transaction update A setamount=amount-10000where userId=1; update B setamount=amount+10000where userId=1;End transactioncommit;非常正确,如果你使用spring的话一个注解就能搞定上述事务功能。@Transactional(rollbackFor=Exception.class) publicvoid update() { updateATable();//更新A表 updateBTable();//更新B表 }如果系统规模较小,数据表都在一个数据库实例上,上述本地事务方式可以很好地运行,但是如果系统规模较大,比如支付宝账户表和余额宝账户表显然不会在同一个数据库实例上,他们往往分布在不同的物理节点上,这时本地事务已经失去用武之地。既然本地事务失效,分布式事务自然就登上舞台。2 分布式事务—两阶段提交协议两阶段提交协议(Two-phase Commit,2PC)经常被用来实现分布式事务。一般分为协调器C和若干事务执行者Si两种角色,这里的事务执行者就是具体的数据库,协调器可以和事务执行器在一台机器上。1) 我们的应用程序(client)发起一个开始请求到TC;2) TC先将《prepare》消息写到本地日志,之后向所有的Si发起《prepare》消息。以支付宝转账到余额宝为例,TC给A的prepare消息是通知支付宝数据库相应账目扣款1万,TC给B的prepare消息是通知余额宝数据库相应账目增加1w。为什么在执行任务前需要先写本地日志,主要是为了故障后恢复用,本地日志起到现实生活中凭证 的效果,如果没有本地日志(凭证),出问题容易死无对证;3) Si收到《prepare》消息后,执行具体本机事务,但不会进行commit,如果成功返回《yes》,不成功返回《no》。同理,返回前都应把要返回的消息写到日志里,当作凭证。4) TC收集所有执行器返回的消息,如果所有执行器都返回yes,那么给所有执行器发生送commit消息,执行器收到commit后执行本地事务的commit操作;如果有任一个执行器返回no,那么给所有执行器发送abort消息,执行器收到abort消息后执行事务abort操作。注:TC或Si把发送或接收到的消息先写到日志里,主要是为了故障后恢复用。如某一Si从故障中恢复后,先检查本机的日志,如果已收到《commit 》,则提交,如果《abort 》则回滚。如果是《yes》,则再向TC询问一下,确定下一步。如果什么都没有,则很可能在《prepare》阶段Si就崩溃了,因此需要回滚。现如今实现基于两阶段提交的分布式事务也没那么困难了,如果使用java,那么可以使用开源软件atomikos(foreach msg inqueue Begin transaction select count(*) ascnt from message_apply where msg_id=msg.msg_id; ifcnt==0then update B setamount=amount+10000where userId=1; insert into message_apply(msg_id) values(msg.msg_id); End transaction commit;