分布式事务

什么是事务 

   事务是并发控制的基本单位,它包含一系列的操作,这些操作要么都被执行,要么都不被执行。

事务有哪些特性

  • 原子性(A),是指事务包含的所有操作要么全部成功,要么全部失败回滚。
  • 一致性(C),是指事务必须使数据库从一个一致性状态变换到另一个一致性状态。
  • 隔离性(I),多个并发事务之间要相互隔离,事务之间不会相互干扰。
  • 持久性(D),事务一旦被提交了,那么对数据库中的数据的改变就是永久性的。

事务隔离级别

   事务隔离级别越高,数据的完整性和一致性越能得到保证,但性能表现会越差。

  • 读未提交,会出现脏读:事务A的修改尚未提交,事务B就开始读了,这会带来脏读、幻读、不可重复读的问题,所以基本不用。

  • 读提交,则不可重复读:事务A完成提交后,可被B事务读取,事务B读取数据在事务A修改该数据提交前后的值不一样。

  • 可重复读,会出现幻读:事务B多次读取同一数据,返回的结果是一样的,避免了脏读与不可重复读问题,但存在幻读的可能,譬如事务A刚确认过最新的id序号,事务B就插入一条记录,事务A再进行插入时报冲突。它是Mysql Innodb的默认隔离级别。

  • 串行化:事务串行化逐个执行,事务提交之后才会继续执行下一个事务,性能最差,执行效率最低。

Mysql事务的实现原理

    MySQL事务执行的过程离不开Redo Log和Undo Log,重做日志Redo Log和回滚日志Undo Log对于MySQL事务的实现起着至关重要的作用。MySQL中事务的原子性和持久性靠Redo Log实现的,事务的一致性靠回滚日志Undo Log实现。

    与Redo Log不同Undo Log记录的是逻辑日志,可以这样理解:当数据库执行一条insert语句时,Undo Log会记录一条对应的delete语句;当数据库执行一条delete语句时,Undo Log会记录一条对应的insert语句;当数据库执行一条update语句时,Undo Log会记录一条相反的update语句。

    除了回滚事务,Undo Log还起着多版本并发控制的作用。当Select语句查询的数据被其他事务锁定时,可以从Undo Log中分析出当前数据之前的版本,从而向客户端返回之前版本的数据。

   

什么是多版本控制

    多版本控制的英文缩写是 MVCC ,就是通过对数据行的多版本管理,来实现数据库的并发控制,它使执行一致性读操作有了保证。换言之,为了查询到正在被另一个事务更新的行时,可以看到被更新之前的值,而不用等待另一个事务释放锁。

多版本控制实现原理

     可重复读的核心是一致性读,在可重复读隔离级别下,事务在启动的时候就拍了快照,这个快照就是事务根据回滚日志(undo log) 和 事务ID(trx_id)构建的一致性视图,这个视图可以让一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。 InnoDB的行数据有多个版本,每个版本都有 row trx_id,每条记录更新的时候都会记录一条 undo log(回滚日志),这条 log 会记录当前事务的 transaction id,记为 row trx_id。

什么是分布式事务

    分布式事务,就是在分布式系统中实现事务,它为分布式系统数据一致性问题提供了解决方案。

    分布式系统架构图例:

分布式事务的理论基础   

    分布式事务是一种柔性事务,CAP原则和BASE理论,为分布式事务解决方案提供了理论基础。

    CAP原则:指分布式系统只能同时满足 “一致性”、“可用性”、“分区容忍性” 中的两个。

    BASE理论:强调最终一致性,每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。允许系统损失部分可用性,允许不同节点进行数据同步的过程存在延时,经过一段时间的修复,能够达到数据的最终一致性。

分布式一致性的解决方案

    2PC 和 3PC 是数据库层面的强一致性解决方案;补偿事务(TCC)和可靠消息是业务层面的最终一致性解决方案。

强一致性解决方案

  • 二阶段提交协议(2PC,Two-phase commit protocol)

第一阶段 - 表决阶段 ,参与者告知协调者自己的决策: 同意(本地作业执行成功)或取消(本地作业执行故障)。第二阶段 - 提交阶段,当且仅当所有的参与者同意提交事务,协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。即参与者将本地操作成败通知给协调者,再由协调者根据所有参与者的反馈情报,决定各参与者是否要提交事务或是中止事务。

缺点:2PC 是同步阻塞的,会导致长久的资源锁定问题,效率会低,存在单点故障问题,有数据不一致的风险。

  • 三阶段提交协议(3PC,Three-phase commit protocol)

改进之处:3PC在2PC基础上做了改进,首先在准备阶段和提交阶段之间增加了预提交阶段,PreCommit是一个缓冲,保证了在最后提交阶段之前各参与节点的状态是一致的。其次3PC 为协调者和参与者都引入了超时机制。3PC相比2PC 在一定程度上降低了数据不一致的可能。

最终一致性解决方案

  • 补偿事务(TCC)

拿如何保证缓存和DB间数据的一致性来举例,在DB中创建一张事务补偿表transaction_log,在更新数据前,先将要更新的数据记录到transaction_log中。transaction_log记录成功后,再去更新业务数据表中的内容,最后更新缓存中的数据。缓存更新成功后,就可以删除transaction_log表中对应的记录。如果缓存更新失败,则transaction_log表中对应的记录就会一直存在,通过定时任务,周期性的扫描transaction_log表中的记录,发现有符合条件的记录,就尝试执行补偿逻辑。

  • Paxos算法

Paxos算法是基于消息传递具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。Zookeeper就是Paxos算法的改进。

分布式事务的应用场景

    分布式事务会在三种场景下产生:跨JVM进程、跨数据库实例、多服务访问单数据库。

  • 缓存与数据库一致

    缓存与数据库出现不一致,往往是因为主从同步延迟导致的,一种解决方案是,在写主库时,待主从同步完成后,再清除缓存,可以避免由于延迟导致从库的脏数据载入缓存,但是这样会延长更新操作的时长,影响更新效率,从而影响系统吞吐量。可以借助binlog或其它方式来异步清除缓存,或者在主库有更新,清除缓存后,从主库读取数据。

  • 主从一致

    主从不一致是主从同步延迟造成的,可利用缓存防止读取脏数据。即通过缓存记录主库更新事件,事件过期时间设定为主从同步延迟的时间,(事件key可以用库、表、主键拼装)。当有读请求时,先读缓存看是否有主库更新事件,如果有则读主库,否则读从库。

  • 双主一致

    双主分两种情况,一种是双主并行作业,另一种是其中一个主作为备份。对于第一种情况,不一致主要是两台主库同时插入记录容易出现自增主键冲突的问题,解决方案是上游生成id避免冲突。第二种情况,出现不一致是因为切换到备份库时可能有同步延迟,解决办法是,用内网dns监测,在同步完成后再进行切换。

  • session一致

    session一致性问题是在WebServer水平扩展的分布式环境下,从不同webserver读取到的session是否一致的。最佳的解决方案是,在后端用数据库或缓存统一存储,即将session存储在后端的存储层(数据库或缓存)中,这样webserver无论重启还是扩容,都不会造成session丢失。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值