假设我们有一组杂货店,其中所有商店的负责人想要查询所有商店的可用消毒剂库存,以便将库存商店转移到商店以平衡所有商店的消毒剂库存数量。该任务由单个事务T执行,该事务 T 是第n个商店的组件T n ,而商店S 0对应于管理器所在的T 0 。 T执行的活动序列如下:
a)交易的组成部分( T ) T 0在总部(head-office)创建。
b) T 0向所有存储发送消息以命令它们创建组件T i 。
c)每个T i在商店“ i”处执行查询以发现可用消毒剂库存的数量并将该数量报告给T o 。
d)每个商店收到指令并更新库存水平,并在需要时发货到其他商店。
但是在这个过程的执行过程中,我们可能会遇到一些问题:
1)原子性属性可能会被违反,因为任何store(S n )可能会被指示两次发送库存,这可能会使数据库处于不一致的状态。为了确保原子性,事务T必须要么在所有站点上提交,要么必须在所有站点中止。
2)然而,商店T n的系统可能会崩溃,并且由于任何网络问题和任何其他原因,T n永远不会收到来自T 0 的指令。那么问题来了,无论是中止还是提交,运行的分布式事务会发生什么?能不能恢复?
两阶段提交协议:该协议的核心意图是解决上述问题,考虑到我们有多个分布式数据库,它们从不同的服务器(站点)运行,比如S 1 , S 2 , S 3 ,….S n .其中每个S i都维护所有相应活动的单独日志记录,并且转换T也被划分为子事务T 1 、T 2 、T 3 、…、 T n并且每个T i分配给S i 。这一切都由每个 S i处的单独事务管理器维护。我们指定任何站点作为协调员。
关于该协议需要考虑的一些要点:
a)在两阶段提交中,我们假设每个站点都记录该站点的操作,但没有全局日志。
b)协调器(C i )在确认分布式事务是否会中止或提交方面起着至关重要的作用。
c)在此协议中,消息在协调器 (C i )和其他站点之间发送。在发送每条消息时,在每个发送站点都会记录其日志,以在必要时帮助恢复。
该协议的两个阶段如下:
第一阶段–
a)首先,协调器(C i )在其站点的日志记录上放置一个日志记录<准备T>。
b)然后,协调器(C i )向执行事务(T) 的所有站点发送准备T 消息。
c)每个站点的事务管理器收到此消息后,准备 T决定是提交还是中止其 T 的组件(部分)。如果组件尚未完成其活动,站点可以延迟,但最终必须发送响应。
d)如果站点不想提交,那么它必须写入日志记录
e)如果站点想要提交,它必须写入日志记录
阶段– 第二 –
第二阶段开始于协调器 (C i ) 从协作执行事务 T 的所有站点收到的响应中止 T 或提交T。但是,某些站点可能无法响应;它可能已关闭,或者已被网络断开连接。在这种情况下,在给出合适的超时期限后,在该时间之后,它将将该站点视为已发送中止 T 。交易的命运取决于以下几点:
a) 如果协调器从T的所有参与站点收到就绪 T,则它决定提交 T。然后,协调器在其站点日志记录
b) 如果站点收到提交 T消息,则在该站点提交 T 的组件,并将其写入日志记录
c) 如果站点收到消息abort T ,它会中止 T 并写入日志记录
d) 但是,如果协调器从一个或多个站点收到中止 T ,它会在其站点上记录
缺点:
a)当 Coordinator 站点故障可能导致阻塞时,将面临两阶段提交协议的主要缺点,因此提交或中止Transaction(T) 的决定可能不得不推迟到 Coordinator 恢复。
b)阻塞问题:考虑一个场景,如果事务(T)持有活动站点的数据项的锁,但在执行过程中,如果协调器失败并且活动站点除了