Java 跨服务器事务管理的完美解决方案 (java跨服务器事务管理)

随着互联网技术的不断发展,分布式系统已经成为了很多企业的标配架构,而 Java 作为一种被广泛应用在分布式系统中的编程语言,在面对分布式事务的管理上也成为了一个重要的问题。由于分布式事务面临着跨网络、跨进程甚至跨语言的复杂情况,因此会涉及到很多挑战和困难。针对这一问题,一些研究者开发了一些跨服务器事务管理的完美解决方案,本文将一一阐述。

传统的分布式事务方案——两阶段提交协议

在介绍跨服务器事务管理的完美解决方案之前,我们先来看一下传统的分布式事务方案——两阶段提交协议。该协议主要包括两个阶段:

之一阶段:

事务协调者向所有参与者发起 prepare 请求,要求参与者准备提交事务。

第二阶段:

事务协调者根据参与者的响应情况决定是否提交事务,具体流程如下图所示:

![两阶段提交协议流程图](https://img-blog.csdn.net/20230625145346808?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2luZGV4LnBuZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/50)

需要注意的是,两阶段提交协议有着一些缺点,如存在单点故障,所有的事务协调者都是串行处理事务等。因此,研究者们开始发现两阶段提交协议并不是一个完美的解决方案。

XA 协议——跨服务器事务管理的一次尝试

XA 协议是为了解决两阶段提交协议的一些局限性而提出的一种新型协议。XA 协议在事务管理中引入了一个新的参与者角色——XA 协议参与者,以及一个协调者角色——事务管理器。具体流程如下:

1. 事务管理器向所有 XA 协议参与者发送 XA START 消息,要求参与者开始准备事务。

2. 所有的 XA 协议参与者接受 XA START 消息后,将自己纳入一个独立的事务中,然后开始执行事务。

3. 当一个 XA 协议参与者需要准备提交时,会向事务管理器发送 XA END 消息。

4. 当所有的 XA 协议参与者都发送了 XA END 消息之后,事务管理器向每个 XA 协议参与者发送 XA PREPARE 消息,询问参与者是否准备提交事务。

5. 如果所有的 XA 协议参与者都准备提交事务,则事务管理器会向每个参与者发送 XA COMMIT 消息。

6. 如果任何一个 XA 协议参与者没有准备提交,则事务管理器会向每个参与者发送 XA ROLLBACK 消息。

XA 协议相比于两阶段提交协议而言,具有更好的性能和可用性,但仍然存在一些缺点,如参与者之间的通讯代价较高、参与者需要额外实现 XA 接口、不支持网络分区等。

基于消息队列的分布式事务解决方案——Seata

近年来,随着云原生和微服务架构的兴起,基于消息队列的分布式事务解决方案也逐渐成为了一种新兴的方案。著名的开源项目 Seata 就是一种支持基于消息队列的分布式事务解决方案。与传统的两阶段提交协议或 XA 协议相比,Seata 解决了许多跨服务器事务管理的瓶颈,如服务间调用的幂等性问题、网络分区容错、横向扩展等。

Seata 的基本架构如下所示:

![Seata 架构图](https://img-blog.csdnimg.cn/20230104135450226.png)

Seata 中主要涉及到三种角色:Transaction Coordinator(TC)、Transaction Manager(TM)以及 Resource Manager(RM)。其中,Transaction Coordinator 和 Transaction Manager 的作用类似于两阶段提交协议中的事务协调者;Resource Manager 则类似于两阶段提交协议中的参与者角色。

Seata 的整个事务过程如下所示:

1. 应用服务向 Seata 的 TM 发送开启全局事务请求(Begin)。

2. TM 向 TC 发送创建全局事务请求,生成对应的全局事务 ID 并返回。

3. TM 向参与全局事务的各个 RM 分别发送创建分支事务请求,并将其与全局事务 ID 关联。

4. 如果所有的 RM 都成功创建了分支事务,则回复 TM 注册成功。

5. TM 向应用服务返回全局事务 ID。

6. 应用服务在执行其业务逻辑并向 Seata 的 RM 发送执行分支事务请求。

7. 如果所有的 RM 执行成功,RM 向 TM 返回执行结果。

8. 当所有分支事务执行成功时,应用服务向 Seata 的 TM 发送提交全局事务请求(Commit)。

9、TM 接收到全局事务触发提交请求,根据分支事务的执行情况向 RM 发送提交分支事务请求。

10. 如果所有的 RM 都成功提交分支事务,则回复 TM 提交成功。

Seata 通过可插拔的架构设计,可以扩展到多种应用场景,同时支持各种常见框架和数据源,例如 Spring Boot、Mybatis 和 MySQL 等。Seata 引入了模块化的设计,提供了丰富的扩展点,所以可以通过开发新的模块、中间件或插件,扩展更多的组件来满足应用的需求。

本文介绍了传统的两阶段提交协议、XA 协议以及基于消息队列的分布式事务解决方案——Seata。可以发现,在跨服务器事务管理的过程中,每种解决方案都具有自身的优点和缺点,需要根据实际场景选择适合的方案。无论哪种方案,都需要考虑局限性和斟酌利弊,为企业应用系统提供更好的分布式事务管理方案。

相关问题拓展阅读:

java中怎么控制事务的一致性

有看情况, 一般是自动提交, 你也可以 手动 自己控制, 有一个失败,提交就失败了

Java中为了控制事务的一致性,会使用插入回滚点、callback方法,保证数据不被篡改,示例如下:

public String delete(String id) {

String ID = id;

 db = new getConnection();

 Connection con = db.getConnection();

 try {

con.setAutoCommit(false);

db.executeUpdate(“delete from helloworld where ID=” + ID); //更新操作1

  茄歼丛db.executeUpdate(“delete from helloworld _book where ID=” + ID); //更新操作2

  db.executeUpdate(“delete from helloworld_user where ID=” + ID); //更新操作3

  con.commit();//提交改亩JDBC事务

  con.setAutoCommit(true);

db.close();

return “success”;

 }

 catch (Exception e) {

  con.rollBack();//回滚JDBC事务

  e.printStackTrace();

db.close();

return “fail”;

  颤樱}

}

不用控制.事务全部成功就一起提交,有一个失败就回滚.这样就保证事务一致性了.

使用spring的aop

Java事务的类型有三种:JDBC事务、JTA(Java Transaction API)事务、容器事务。

1、JDBC事务

JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 java.sql.Connection 提供了以下控制事务的方法:

public void setAutoCommit(boolean)

public boolean getAutoCommit()

public void commit()

public void rollback()

使用 JDBC 事务界定时,您可以将多个 SQL 语句结合到一个事务中。JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。

2、JTA(Java Transaction API)事务

JTA是一种高层的,与实现闭御明无关的,与协议无关的API,应用程序和应用服务器可以使用JTA来访问事务。

JTA允许应用程序执行分布式事务处理–在两个或多个网络计算机资源问并且更新数据,这些数据可以分布在多个数据库上。JDBC驱动程序的JTA支持极大地增强了数据访问能力。

如果计划用 JTA 界定拆胡事务,那么就需要有一个实现 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。 XAConnection s 是参与 JTA 事务的 JDBC 连接。

您将需要用应用服务器的管理工具设置 XADataSource 。从应用服务器和 JDBC 驱动程序轿告的文档中可以了解到相关的指导。

J2EE 应用程序用 JNDI 查询数据源。一旦应用程序找到了数据源对象,它就调用 javax.sql.DataSource.getConnection() 以获得到数据库的连接。

XA 连接与非 XA 连接不同。一定要记住 XA 连接参与了 JTA 事务。这意味着 XA 连接不支持 JDBC 的自动提交功能。同时,应用程序一定不要对 XA 连接调用 java.sql.Connection.commit() 或者 java.sql.Connection.rollback() 。

相反,应用程序应该使用 UserTransaction.begin()、 UserTransaction.commit() 和 serTransaction.rollback() 。

3、容器事务

容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。相对编码实现JTA事 务管理,我们可以通过EJB容器提供的容器事务管理机制(CMT)完成同一个功能,这项功能由J2EE应用服务器提供。这使得我们可以简单的指定将哪个方 法加入事务,一旦指定,容器将负责事务管理任务。这是我们土建的解决方式,因为通过这种方式我们可以将事务代码排除在逻辑编码之外,同时将所有困难交给J2EE容器去解决。使用EJB CMT的另外一个好处就是程序员无需关心JTA API的编码,不过,理论上我们必须使用EJB。

总结:

事务控制是构建J2EE应用不可缺少的一部分,合理选择应用何种事务对整个应用系统来说至关重要。一般说来,在单个JDBC 连接连接的情况下可以选择JDBC事务,在跨多个连接或者数据库情况下,需要选择使用JTA事务,如果用到了EJB,则可以考虑使用EJB容器事务。

java跨服务器事务管理的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java跨服务器事务管理,Java 跨服务器事务管理的完美解决方案,java中怎么控制事务的一致性的信息别忘了在本站进行查找喔。


数据运维技术 » Java 跨服务器事务管理的完美解决方案 (java跨服务器事务管理)