当前位置:首页 > 问答 > 正文

Oracle分布式事务里最先提交的那几个关键阶段到底是咋回事,简单聊聊这三步怎么走

整理自Oracle官方文档、Oracle Base网站、AskTOM问答以及多位OCM认证专家的技术分享)

好的,咱们就抛开那些让人头疼的专业术语,像聊天一样,把Oracle分布式事务里最先提交的那几个关键阶段捋清楚,你可以把一次跨数据库的转账操作想象成一次需要多方协同的军事行动,而分布式事务的提交,就是总指挥部下达“最终攻击命令”的过程,这个命令不能乱下,必须确保所有参与方都准备好了,要么一起成功,要么全部撤回,这个过程最核心的开头几步,就是准备阶段、预提交阶段和提交阶段,下面咱们一步步拆解这三步是怎么走的。

第一步:准备阶段——挨个问“兄弟,你准备好了吗?”

当你在一个数据库(比如我们叫它“北京数据库”)里执行了转账操作,并发出COMMIT命令时,好戏就开始了,Oracle首先会意识到,这个事务不光牵扯到北京的数据,还牵扯到另一个数据库(上海数据库”)里的数据,这时候,北京数据库的角色就自动升级为“全局协调者”,相当于这次行动的总指挥。

总指挥要做的第一件事,不是莽撞地直接让大家行动,而是先确认所有参与单位是否就绪。

  • 北京数据库(协调者) 会向所有参与这个事务的远程数据库(比如上海数据库)发送一条询问信息,这条信息的核心意思就是:“我这边有个事务要最终提交了,你那边和这个事务相关的操作都完成了吗?你现在有没有能力保证,一旦我下令,你就能立刻成功提交;万一我下令撤回,你也能干净利落地撤销所有影响?”

  • 上海数据库(参与者) 收到这个“准备”询问后,会立刻进行自我检查,它会把自己内部和这个事务相关的所有信息(比如修改了哪些数据块、生成了哪些日志)都稳固地记录到自己的重做日志文件中,这个动作非常关键,相当于把“作战计划”白纸黑字地存档了,一旦存档完成,上海数据库就会锁住相关数据,防止别人在这个时候来捣乱,它会给北京数据库回信,内容是:“我准备好了”(技术上称为PREPARED状态)。

  • 潜在问题:如果上海数据库在准备过程中出了岔子,比如磁盘满了导致日志写不进去,或者它发现事务存在约束冲突(比如要扣款的账户不存在),它就会回信说“我准备不了”(ABORT状态),总指挥北京数据库一旦收到任何一个参与者的“准备不了”的信号,就会立即决定终止整个行动,通知所有参与者回滚。

这个准备阶段是整个分布式事务的基石,它的目的就是消除不确定性,确保在真正点下“提交”按钮之前,所有参与者都已经表态,承诺自己有能力完成最终任务,这就像发射火箭前的最后读秒检查,每一个环节都必须回报“正常”。

第二步:预提交阶段——其实这是个“心理建设”阶段,但名字容易误会

很多人看到“预提交”这个词,会以为它是在真正提交之前先试一下,其实不然,在Oracle经典的两阶段提交协议中,“预提交”这个动作并不是一个独立的、需要额外通信的阶段,它本质上就是第一步“准备”动作在参与者(上海数据库)内部执行的一个关键操作。

当上海数据库收到“准备”指令后,它所做的事情就是“预提交”,具体包括:

  1. 将事务的状态设置为“已准备”。
  2. 将足够用于提交或回滚该事务的所有信息(主要是重做日志记录)强制写入磁盘上的日志文件,这个“强制写入”保证了即使此时数据库突然断电重启,在恢复阶段也能知道有这个一个处于“准备”状态的事务,并能根据协调者的最终指令决定它的命运。
  3. 获取必要的锁,使事务的更改暂时与外界隔离。

更准确的理解是:准备阶段是由协调者发起的全局询问流程,而每个参与者响应这个询问时所执行的内部操作,就是预提交。 你可以认为“预提交”是“准备阶段”的核心动作,完成这个动作后,参与者的事务就进入了一种“悬而未决”但“高度稳定”的状态,它不能再做任何改变,只等待协调者的最终判决,这个阶段之后,参与者已经付出了绝大部分的代价(写了日志,拿了锁),就等那临门一脚了。

第三步:提交阶段——总指挥下达最终命令“开干!”

当北京数据库(协调者)收到了所有参与者(包括它自己)的“准备就绪”信号后,整个分布式事务的命运就决定了——只能提交,不能回滚,因为所有参与者都已经承诺可以提交了。

这时,提交阶段正式启动:

  1. 决策与记录:北京数据库首先将“全局提交”这个最终决定,永久性地记录到它自己的重做日志文件中,这是一个至关重要的点,因为万一协调者在通知大家的过程中崩溃了,重启后它查看日志,看到这个“全局提交”的记录,就知道必须继续完成通知所有参与者的任务。
  2. 发送指令:北京数据库会向上海数据库发送“现在提交”的指令。
  3. 本地提交:几乎在发出远程指令的同时(为了效率),北京数据库也会完成它自己本地那部分事务的提交。
  4. 参与者执行:上海数据库收到“提交”指令后,因为它早在“预提交”阶段就万事俱备了,所以此时要做的非常简单高效:只需要在本地做一个快速的提交操作(比如写一个提交记录到日志),然后释放事务持有的锁,这个动作通常瞬间就能完成。
  5. 确认回复:上海数据库提交成功后,会向北京数据库回复一条“提交完成”的确认信息。

一旦北京数据库收到所有参与者的确认,整个分布式事务就宣告彻底完成,你会发现,提交阶段的核心工作就是“通知”和“确认”,因为最繁重、最耗时的确保数据持久化的工作,已经在之前的准备(预提交)阶段做完了,这使得最终的提交操作非常快速。

总结一下这三步怎么走:

就是总指挥(协调者)问一圈(准备阶段):“都能干吗?”各个分部(参与者)立刻立下军令状并存档(预提交):“能!我保证!”然后总指挥看到大家都保证好了,就正式下令(提交阶段):“好,现在开始干!”分部们收到命令,迅速执行早已准备好的最后手续,然后报告完成。

这个过程精妙地平衡了安全与性能,通过“准备阶段”排除了所有不确定性,确保了分布式系统下数据的最终一致性,虽然我们这里略过了异常处理(比如网络中断、节点宕机等)的复杂细节,但这个“三步走”流程是理解整个Oracle分布式事务提交机制的基石。

Oracle分布式事务里最先提交的那几个关键阶段到底是咋回事,简单聊聊这三步怎么走