JAVA:本地事务与分布式事务技术实践与挑战

1、简述

随着企业规模的扩大和业务复杂性的增加,分布式系统的应用变得越来越普遍。在这样的环境中,事务处理变得尤为重要,而本地事务和分布式事务则成为了两个不可忽视的关键概念。本文将深入探讨本地事务和分布式事务的技术实践,探讨其优势、挑战以及解决方案。

2、本地事务

2.1 事务的基本性质

数据库事务四大特性: Atomic原子性、Consistency一致性、Isolation隔离性和Durability持久性,简称就是ACID

  • 持久性:当事务回滚或者提交之后,数据库会持久化数据
  • 一致性:事务操作前后,数据的总量不变
  • 原子性:是不可分割的最小单位,不可分割,要么同时成功要么同时失败,不可分割
  • 隔离性:各个事务之间相互独立
2.2 事务的隔离级别

隔离级别从低到高分为四级:
在这里插入图片描述

  • Read uncommitted(读未提交)
    该隔离级别的事务会读到其他未提交事务的数据,此现象也称为脏读。
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
  • Read committed(读已提交)
    一个事务可以读取另一个已提交的事务,多次读取会造成不一样的结果,此现象称为不可重复读问题,Oracle和SQL Server的默认隔离级别。
@Transactional(isolation = Isolation.READ_COMMITTED)
  • Repeatable read(可重复读取)
    该隔离级别是MySql默认的隔离级别,在同一个事务里,Select的结构是事务开始时时间点的状态,因此,同样的Select操作读到的结果是一致的,但是会出现幻读现象。Mysql的InnoDb引擎可以通过next-key locks机制来避免幻读。
@Transactional(isolation = Isolation.REPEATABLE_READ)
  • Serializable(串行化)
    在该隔离级别下事务都是串行顺序执行的。Mysql数据库的InnoDb引擎会给读操作隐式加一把共享锁。从而避免了脏读,不可重复读和幻读的问题。
@Transactional(isolation = Isolation.SERIALIZABLE)
2.3 事务的传播行为
  • Propagation.REQUIRED
    如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。

  • Propagation.SUPPORTS
    如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。

  • Propagation.MANDATORY
    如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。

  • Propagation.REQUIRES_NEW
    重新创建一个新的事务,如果当前存在事务,延缓当前的事务。

  • Propagation.NOT_SUPPORTED
    以非事务的方式运行,如果当前存在事务,暂停当前的事务。

  • Propagation.NEVER
    以非事务的方式运行,如果当前存在事务,则抛出异常。

  • Propagation.NESTED
    如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务。

2.4 同一个对象内本地事务调用失败问题

解决方法:采用代理对象来调用事务方法

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

开启AspectJ动态代理,没有接口也可以创建动态代理

@EnableAspectJAutoProxy(exposeProxy = true)

通过AopContext就可以调用对象内事务方法。

WareSkuService skuService = (WareSkuService)AopContext.currentProxy();
skuService.GetSkuHasStock(null);

3、分布式事务

3.1 CAP定理

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。

  • 一致性(Consistency)
    在分布式系统中的所有数据备份,在同一时刻是否有同样的值(等同于所有节点访问同一份最新的数据副本)
    分布式实现一致性算法:
    http://thesecretlivesofdata.com/raft/
  • 可用性(Availability)
    在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
  • 分区容错性(Partition tolerance)
    大多数分布式系统都分布在多个子网格。每个子网格就叫做一个区。分区容错的意思是,区间通信可能失败。比如,一台服务器在中国,另外一台服务器在美国,这就是两个区,他们之间可能无法通信。

备注:这三个要素最多只能同时实现两点(CP、AP),不可能三者兼顾

3.2 BASE理论

是对CAP理论的延伸,就是即使无法做到强一致性,也可以采用弱一致性,即最终一致性。

  • 基本可用
    指的是分布式系统出现故障时,允许损失部分可用性(如响应时间),基本可用不等价于系统不可用。
    响应时间上的损失,引擎响应延迟。
    网站购物高峰期,页面的降级引导。
  • 软状态
    指的是允许系统存在中间状态,而该中间状态不会影响到整个系统的可用性。分布式存储一般一份数据有多个副本,允许不通副本同步的延时就是软状态的体现。mysql replication的异步也是一种体现。
  • 最终一致性
    指的是系统中所有数据副本经过一定时间后,最终能够达到一致的状态,弱一致性和强一致性想法。最终一致性是弱一致性的特性情况。
3.3 分布式事务实现方案
  • 2PC模式
    数据库二阶提交,一阶预备提交,二阶提交数据,简称XA
    在这里插入图片描述

  • 柔性事务-TCC事务补偿协议
    柔性事务,遵循BASE理论,实现最终一致性。
    一阶段prepare行为。
    二阶段commit行为。
    三阶段rollback行为。
    比较典型的事务:
    由阿里云提供的Seata
    http://seata.io/zh-cn/docs/user/quickstart.html
    在这里插入图片描述

  • 柔性事务-最大努力通知方案
    不一定通知成功,但会提供可查询接口进行核对。
    当前方案,可以结合MQ来实现。
    案例(银行通知,商户通知,支付宝支付成功异步调用等)

  • 柔性事务-可靠消息+最终一致性
    实现业务处理服务在业务提交之前,向MQ实时消息服务请求发送消息。实时消息只记录消息数据,而不是真真的发送。业务处理服务在业务提交之后,向实时消息服务确认发送,只有在确认收到发送指令后,才会真正的发送实时消息。

4、结论

本地事务和分布式事务都有各自的优势和挑战。在实际应用中,开发人员需要根据业务需求和系统规模的不同权衡它们。深入了解事务管理的原理和实践,以及利用现代技术手段来解决分布式事务带来的挑战,将有助于构建稳健、高性能的分布式系统。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾荒的小海螺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值