Java专家之路(三)---事务知识体系的总结

版权声明:本文为博主原创文章,大家喜欢的话,多多转载吧! https://blog.csdn.net/u011500356/article/details/79649884

引言:

本文的意图在于:在帮助大家,从最简单的事务概念ACID开始,

  • 宏观掌握事务的知识体系
  • 通过demo实战来掌握各类事务,尤其是分布式事务的概念和原理
  • 不同事务模型的事务处理办法
  • java中常见的事务设计策略
  • 理解和实战微服务下分布式事务的解决方案

同时,我们的重点将会是分布式事务的一些知识、实践和讨论

导图宏观概览:

这里写图片描述

那么,事务到底是什么?

生活中的事务

举个很经典的例子:
用户A给用户B转账5000元主要步骤可以概括为如下两步。
  第一,账户A账户减去5000元;
  第二,账户B账户增加5000元;
  这两步要么成功,要么全不成功,否则都会导致数据不一致。这就可以用到事务来保证,如果是不同银行之间的转账还需要用到分布式事务。

小结:   
  原子性:构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行。
  稳定性:数据库在事务执行前后状态都必须是稳定的。
  隔离性:事务之间不会相互影响。
  持久性:事务执行成功后必须全部写入磁盘

相关概念以及相互关系(外延)

事实上,我们在现实中有很多的分类标准和角度,导致事务这个技术体系有很多名词儿和概念,让人一看就发憷头疼。下面简单说下个人的看法:

第一种分类方式:

从事务的实现技术上,是否由资源管理器来处理本地事务,来给事务的模型进行分类:大概可以分为三大类事务模型:

  • 本地事务模型

  • 编程式模型

  • 声明式事务模型

第二种分类方式:从是否跨越多个/种数据源来分类。分为两大类

  • 本地事务
  • 分布式事务(全局事务)

第三种分类方式:按照解决方案的技术特点点来划分。

  • 刚性事务(基于DTP模型的标准分布式事务 / 基于XA、2PC协议的全局事务),典型实现方式是JavaEE平台的JTA + JTS + EJB

  • 柔性事务(基于CAP、BASE、ACID-BASE Balance(酸碱平衡)理论的互联网型微服务架构下的分布式事务解决办法),主要代表有:

  • 可靠消息最终一致(异步确何型),例如:支付宝、eBay(BASE)、去哪儿……
  • TCC (两阶段型、补偿型),例如:支付宝XTS(蚂蚁金融云的分布式事务服务DTS)
  • 最大努力通知(非可靠消息 、定期校对),例如: 银行通知、商户通知等(各大交易业务平台间的商户通知:多次通知、查询校对、对账文件)

技术中事务的本质

逻辑上的一个整体单元。它具备ACID四个特性,他们的最终目的是确保一系列逻辑操作后的数据能够可靠。

为什么需要事务?

总而言之三句话:

  • 数据库事务 = ACID
  • ACID 的需求是数据可靠性。
  • 保护数据可靠性,A / D 是基础,而 C / I 看业务场景。

事务的前世今生:

参考博客:理解ACID

事务要做什么?

通过应用程序、应用程序服务器、TM(事务管理程序 )、资源适配器(JDBC/ODBC 驱动程序)、资源管理器(数据库软件、JMS等消息中间件的实现产品……)之间的协调合作,帮助我们确保数据的可靠性。实现事务的特性:A(原子性)C(一致性)I(隔离性)D(持久性)。

理论体系(分布式事务)

注意:(以下的概念均和语言、架构、框架等技术无关),属于规范和协议层面的内容

X/Open DTP

DTP全称是Distributed Transaction Process,即分布式事务模型。之前我们接触的事务都是针对单个数据库的操作,如果涉及多个数据库的操作,还想保证原子性,这就需要使用分布式事务了。而X/Open DTP就是一种分布式事务处理模型。
这里写图片描述

  • AP(Application Program):应用程序
  • TM(Transaction Manager):事务管理器负责协调和管理事务

  • RM(Resource Manager):资源管理器,可以理解为数据库或者JMS。

他们三者的关系:

  • AP通过TM来操作多个RM,AP也可以通过RM的本地事务接口来操作单个RM
  • M和RM可以互相通信,他们之前的通信协议就是XA协议

XA

X/Open XA 接口是双向的系统接口,在事务管理器(Transaction Manager)以及一个或多个资源管理器(Resource Manager)之间形成通信桥梁。

2PC

两阶段提交协议(The two-phase commit protocol,2PC)是 XA 用于在全局事务中协调多个资源的机制。

两阶段协议遵循 OSI(Open System Interconnection,开放系统互联)/DTP 标准,虽然它比标准本身早若干年出现。

两阶段提交协议包含了两个阶段:第一阶段(也称准备阶段)和第二阶段(也称提交阶段)。

CAP

缩写 CAP 代表 Consistency(一致性), Availability(可用性)和 Partition tolerance(分区容忍性),注意:这里的 Consistency 与 ACID 里的数据一致性(C)不一样。这里指数据在分布式节点的一致性。

CAP 定理断言,任何一个分布式系统都不可能同时满足 C-A-P 三个特性:

C -- 从每个节点读到相同的数据。
A -- 从任何位置发起的读写请求都能够成功返回。
P -- 即使出现分区(部分隔离),也能响应请求。

BASE

这个理论由 Basically Available, Soft state, Eventual consistency 组成。核心的概念是 Eventual consistency ——最终一致性。它局部的放弃了 CAP 理论中的“完全”一致性,提供了更好的可用性和分区容忍度。

小结:三者的关系如何?

在英文词典里,ACID 代表 酸(Acid),而 BASE 代表 碱(Base)。就像这两个单词在化学中的含义一样 —— ACID 与 BASE 位于 CAP 理论的两端,代表了分布式系统的两种选择。

传统数据库用 ACID 保护业务数据的一致性。它明确的要求:事务必须保证数据从上一个一致性状态进入下一个一致性状态,事务的结束和数据的一致性之间没有时差。

从 CAP 定理我们可以知道:正是 ACID 要求的这种“强”一致性,使得事务系统只能选择 C-A 或者 C-P。第一个选择实际上是单机的传统数据库,第二个选择是后面将要介绍的强一致性的数据复制集群。

而 BASE 代表了另一种选择:放弃一致性 来保证分布式系统的高可用。与 ACID 的做法相反:业务需要接受和处理数据的不一致,并且保证这些不一致不会破坏业务约束 —— 这需要设计者对可能产生的数据不一致和业务约束非常了解,并且带来了更高的复杂度。

选择 高可用 的价值在于:很多场景下系统不可用就意味着对外停止服务,对用户的影响和商业风险远远比“系统仍然可用但是要过一会才能看到数据”来得严重。在一些场景下,用户或许根本不在乎过一会才能看到数据,例如 银行跨行转账。但是,如果银行告诉用户无法进行跨行转账,那么就会有很多用户质疑或投诉银行的服务了。

上面的 CAP 拼图里还剩下一个区域。前面讨论过的 ACID 理论占据了 C-A 区域,代表根本无法容忍分区的传统单机数据库。本文介绍的 BASE 理论位于 A-P 区域,代表部分放弃一致性、追求高可用的现代业务系统。

how?实战demo:

本地事务管理(mysql的事务管理为例)

本地资源管理器(local resource manager)来管理的。资源管理器是用于通信的、事实上的数据源(datasource)提供者。

举例来说,对于数据库,资源管理器是通过数据库驱动和数据库管理系统(Database Management System,DBMS)来实现的。对于 JMS,所谓资源管理器就是通过特定的 JMS 提供者(provider)实现的队列(queue)或主题(topic)的连接工厂(connectionfactory)。

经由本地事务模型,开发人员管理的是“连接(connection)”,而非“事务”。DBMS和 JMS 的提供者真正管理了本地事务。

mysql数据库中的事务实战

demo1:https://www.cnblogs.com/snsdzjlz320/p/5761387.html
demo2:https://www.cnblogs.com/ivanpan/p/6653990.html

mysql数据库事务的实现原理

MySQL事务介绍及原理

MySQL日志——Undo | Redo

Innodb中的事务隔离级别和锁的关系

本地事务的代码示例:

注:直接使用 JDBC 编码来进行本地事务模型管理的实例

public void updateTradeOrder(TradeOrderData order)
 throws Exception {
 DataSource ds = (DataSource)
 (new InitialContext()).lookup("jdbc/MasterDS");
 Connection conn = ds.getConnection();
 conn.setAutoCommit(false);
 Statement stmt = conn.createStatement();
 String sql = "update trade_order ... ";
 try {
 stmt.executeUpdate(sql);
 conn.commit();
 } catch (Exception e) {
 conn.rollback();
 throw e;
 } finally {
 stmt.close();
 conn.close();
 }
} 

小结:从开发人员的角度来看,在本地事务模型中,我们所管理的并非“事务”,而是“连接”。

编程事务:

概念介绍:

编程式事务模型和本地事务模型两者最大区别之一是,开发人员使用编程式模型,管理的是事务(transaction),而不是连接(connection)。

当在 EJB 中时,编程式事务模型常常被称为Bean 管理事务(Bean-Managed Transactions),或 BMT。“BMT”这个术语不太常使用,因为在 EJB 容器之外,编程式事务模型也可用在 servlet 容器之中,能应用于 POJO(而不仅仅是EJB)。

实战demo

基于JbossEAP版EJB的实现方式(EJB, CMT, JMS)
基于Spring框架的实现方式:(待完善……)

声明式事务:

概念介绍:

如我们在编程式事务模型中看到的,开发人员必须显示的调用 begin()方法去开启事务,调用 commit()或和 rollback()去提交或回滚事务。

如果使用声明式事务模型(DeclarativeTransaction Model),容器将管理事务,这意味着开发人员不用编写任何代码,便可开始或提交事务了。

然而,开发人员必须要告诉容器“如何”去管理事务。

实战demo:

于JbossEAP版EJB的实现方式(EJB, BMT)
于JbossEAP版EJB的实现方式( JTS, EJB, JMS)
于JbossEAP版EJB的实现方式( JTS, Crash Recovery)
基于Spring框架的实现方式:(待完善……)

java中常见的事务设计策略(待完善……,详情参见java事务设计策略)

客户端拥有事务

领域拥有事务

服务端代理拥有事务

如何做选择?

详情参看《java事务设计策略》

实战微服务架构的分布式事务

http://www.roncoo.com/course/view/7ae3d7eddc4742f78b0548aa8bd9ccdb
https://github.com/roncoo/roncoo-pay
http://www.roncoo.com/article/detail/124373
http://www.roncoo.com/article/detail/124511

参考资源链接

《Java事务设计策略》
AVA分布式事务原理及应用
漫谈事务与分布式事务系列
聊聊分布式事务,再说说解决方案
深入理解分布式事务,高并发下分布式事务的解决方案

猜你喜欢

转载自blog.csdn.net/u011500356/article/details/79649884