PostgreSQL-分布式事务之两阶段提交

这篇具有很好参考价值的文章主要介绍了PostgreSQL-分布式事务之两阶段提交。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是ACID

在日常操作中,对于一组相关操作,通常需要其全部成功或全部失败。

在关系型数据库中,将这组相关操作称为“事务”。

在一个事务中,多个插入、修改、删除操作要么全部成功,要么全部失败,这称为“原子性”,实际上一个事务还需要有其他三个特性,即“一致性”“隔离性”“持久性”,英文简称为“ACID”:

  • 原子性(Atomicity):事务必须以一个整体单元的形式进行工作,对于其数据的修改,要么全部执行,要么全都不执行。如果只执行事务中多个操作的前半部分就出现错误,那么必须回滚所有的操作,让数据在逻辑上回滚到原先的状态
  • 一致性(Consistency):在事务完成时,必须使所有的数据都保持在一致状态。(AB转账,A账户5000元,不论他怎么转给B,AB账户合计还是5000元,这就是一致性)
  • 隔离性(Isolation):事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务是不会查看中间状态的数据的
  • 持久性(Durability):事务完成之后,它对于系统的影响是永久性的,即使今后出现致命的系统故障(如机器重启、断电),数据也将一直保持

在PG中,可以使用多版本并发控制(MVCC)来维护数据的一致性。相比于锁定模型,其主要优点是在MVCC下对检索(读)数据的锁请求与写数据的锁请求不冲突,读不会阻塞写,而写也不会阻塞读

在PG中提供了表和行级别的锁定语句,让应用能更方便地操作并发数据。

DDL事务

在PG中,与其他数据库最大的不同是,大多数DDL也是可以包含在一个事务中的,而且也是可以回滚的。该功能非常适合把PG作为Sharding的分布式数据系统的底层数据库。

比如在Sharding中常常需要在多个节点中建相同的表,此时可以考虑把建表语句放在同一个事务中,这样就可以在各个节点上先启动一个事务,然后再执行建表语句,如果某个节点执行失败,也可以回滚前面已执行建表成功的操作,自然就不会出现部分节点建表成功,部分节点建表失败的情况。

事务的使用方法

手动设置

set AUTOCOMMIT off

PostgreSQL-分布式事务之两阶段提交

BEGIN语句

PostgreSQL-分布式事务之两阶段提交

SAVEPOINT

PG支持保存点(SAVEPOINT)的功能,在一个大事务中,可以把操作过程分为几个部分,第一个部分执行成功后可以建一个保存点,若后面的部分执行失败,则回滚到此保存点,而不必回滚整个事务。

PostgreSQL-分布式事务之两阶段提交

事务隔离级别

数据库的事务隔离级别有以下4种(不同的数据库可能不同):

  • READ UNCOMMITTED:读未提交
  • READ COMMITTED:读已提交
  • REPEATABLE READ:重复读
  • SERIALIZABLE:串行化

对于并发事务,我们不希望发生不一致的情况,这类情况的级别从高到低排序如下:

  • 脏读:一个事务读取了另一个未提交事务写入的数据。这是我们最不希望发生的,因为如果发生了脏读,则在并发控制上,应用程序会变得很复杂
  • 不可重复读:指一个事务重新读取前面读取过的数据时,发现该数据已经被另一个已提交事务修改了。在大多数情况下,这还是可以接受的,只是在少数情况下会出现问题
  • 幻读:一个事务开始后,需要根据数据库中现有的数据做一些更新,于是重新执行一个查询,返回一套符合查询条件的行,这时发现这些行因为其他最近提交的事务而发生了改变,此时现有的事务如果再进行下去的话,就可能会导致数据在逻辑上的一些错误。

不同事务隔离级别下的行为:

  1. 读未提交:脏读、不可重复读、幻读
  2. 读已提交:不可重复读、幻读
  3. 重复读:幻读
  4. 可串行化:不会发生以上行为

对幻读理解不清楚的,可以参考以下实例

幻读实例

数据准备

PostgreSQL-分布式事务之两阶段提交

开启事务更新数据

PostgreSQL-分布式事务之两阶段提交
更新操作执行完之后,新开启一个事务插入一条数据
PostgreSQL-分布式事务之两阶段提交

更新操作事务提交后,发现有一条数据id=4未更新,像产生了幻觉一样,这就是幻读

PG事务隔离级别

  • 9.1版本之前只有读已提交和可串行化
  • 9.1版本之后增加了重复读

也就是说在PG中,如果你选择了读未提交的级别,实际上还是读已提交;如果选择可重复读级别,有可能实际上仍是可串行化。

PG中默认的隔离级别是读已提交。当一个事务运行于这个隔离级别时,执行SELECT查询(没有FOR UPDATE/SHARE子句)只能看到查询开始之前已提交的数据,而无法看到未提交或者查询期间其他事务已提交的数据;可以看到自身所在事务前面尚未提交的更新结果。实际上,SELECT查询看到的是查询开始运行瞬间的一个快照。

注意:同一个事务中两个相邻的SELECT命令可能看到不同的快照,因为可能有其他事务在第一个SELECT执行完之后,提交了更新结果

两阶段提交

PG数据库支持两阶段提交协议

在分布式系统中,事务中往往包含了多台数据库上的操作,虽然单台数据库的操作能够保证原子性,但多台数据库之间的原子性就需要通过两阶段提交来实现了,两阶段提交是实现分布式事务的关键

两阶段提交有如下5个步骤:

  1. 应用程序先调用各台数据库做一些操作,但不提交事务。然后应用程序调用事务协调器(该协调器可能也是由应用自己实现的)中的提交方法
  2. 事务协调器将联络事务中涉及的每台数据库,并通知它们准备提交事务,这是第一阶段的开始。PG中一般是调用PREPARE TRANSACTION命令
  3. 各台数据库接收到PREPARE TRANSACTION命令后,如果要返回成功,则数据库必须将自己置于如下状态:确保后续能在被要求提交(回滚)事务的时候提交(回滚)事务,所以PG会将已准备好提交的信息写入持久存储区中。如果数据库无法完成此事务,它会直接返回失败给事务协调器
  4. 事务协调器接收所有数据库的响应
  5. 在第二阶段,如果任何一个数据库在第一阶段返回失败,则事务协调器将会发一个回滚命令ROLLBACK PREPARED给各台数据库。如果所有数据库的响应都是成功的,则向各台数据库发送COMMIT PREPARED命令,通知各台数据库事务成功

两阶段提交实例

配置max_prepared_transactions

PostgreSQL-分布式事务之两阶段提交
PostgreSQL-分布式事务之两阶段提交

重启服务

PostgreSQL-分布式事务之两阶段提交

二阶段提交

PostgreSQL-分布式事务之两阶段提交

  • 第一阶段:PREPARE TRANSACTION ‘osdba_global_trans_0001’
  • 第二阶段:COMMIT PREPARED ‘osdba_global_trans_0001’

注意:第一阶段结束后,重启服务,模拟数据库宕机。服务重启后,第二阶段提交,数据可以正常查询。

上述命令osdba_global_trans_0001是两阶段提交中全局事务的ID,由事务协调器生成(事务协调器会持久化该ID)。PG数据库一旦成功执行这条命令,也会把事务持久化,即使数据库重启,此事务也不会回滚或丢失文章来源地址https://www.toymoban.com/news/detail-443308.html

到了这里,关于PostgreSQL-分布式事务之两阶段提交的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【分布式事务】Seata 开源的分布式事务解决方案

    Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。 阿里巴巴作为国内最早一批进行应用分布式(微服务化)改造的企业,很早就遇到微服务架构下

    2024年02月02日
    浏览(53)
  • 【分布式】分布式事务:2PC

    分布式事务的问题可以分为两部分: 并发控制 concurrency control 原子提交 atomic commit 分布式事务问题的产生场景:一份数据被分片存在多台服务器上,那么每次事务处理都涉及到了多台机器。 可序列化(并发控制): 定义了事务执行的正确性 真正地并行执行事务,获得真正的

    2024年02月09日
    浏览(46)
  • Redis分布式锁和分布式事务

    Redis分布式锁和分布式事务 一、Redis分布式锁 1.1 watch和事务实现分布式锁 原理是通过watch来观察一个变量,一个线程在操作的时候,其他线程会操作失败,相当于乐观锁。 1.2 setnx实现分布式锁 原理是通过setnx设置一个变量,设置成功的线程抢到锁,执行相关的业务,执行完毕

    2024年02月09日
    浏览(45)
  • 分布式软件架构——分布式事务TCC和SAGA

    TCC 是另一种常见的分布式事务机制,它是“ Try-Confirm-Cancel ”三个单词的缩写,是由数据库专家 Pat Helland 在 2007 年撰写的论文《Life beyond Distributed Transactions: An Apostate’s Opinion》中提出。 前面介绍的可靠消息队列虽然能保证最终的结果是相对可靠的,过程也足够简单(相对于

    2024年02月12日
    浏览(44)
  • 【分布式】java实现分布式事务的五种方案

    用户支付完成会将支付状态及订单状态保存在订单数据库中,由订单服务去维护订单数据库。由库存服务去维护库存数据库的信息。下图是系统结构图: 如何实现两个分布式服务(订单服务、库存服务)共同完成一件事即订单支付成功自动减库存,这里的关键是如何保证两个

    2024年04月11日
    浏览(49)
  • 微服务·数据一致-事务与分布式事务

    事务是计算机科学和数据库管理中的一个关键概念,用于确保数据的一致性和可靠想。事务管理是大多数应用程序和数据库系统中不可或缺的一部分。分布式事务扩展了事务的概念,用于多个分布式系统和服务的数据一致性管理。本调查报告将深入探讨事务和分布式事务的概

    2024年02月09日
    浏览(45)
  • Flink实战(11)-Exactly-Once语义之两阶段提交

    [Apache Flink]2017年12月发布的1.4.0版本开始,为流计算引入里程碑特性:TwoPhaseCommitSinkFunction。它提取了两阶段提交协议的通用逻辑,使得通过Flink来构建端到端的Exactly-Once程序成为可能。同时支持: 数据源(source) 和输出端(sink) 包括Apache Kafka 0.11及更高版本。它提供抽象层

    2024年02月05日
    浏览(37)
  • Seata分布式事务

    本地事务,也就是传统的单机事务。在传统数据库事务中,必须要满足四个原则: 分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务,例如: 跨数据源的分布式事务 跨服务的分布式事务 综合情况 完成上面的操作需要访问三个不同的微服务和三个不同的

    2024年02月09日
    浏览(44)
  • 分布式事务详解

    随着互联网的发展,软件系统由原来的单体应用转变为分布式应用。分布式系统把一个单体应用拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作。这种分布式系统下不同服务之间通过远程协作完成的事务称之为分布式事务,例如用户注册送

    2024年02月19日
    浏览(38)
  • Springboot分布式事务

    1. 概念 本地事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器位于同一节点相同数据库上。 又称为传统事务。它是一个操作序列,这些操作要么都执行,要么都不执行,是一个不可分割的工作单位。例如,银行转账工作:从一个帐号扣款并使另一个帐

    2024年02月09日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包