Seata-AT模式数据源代理-JDBC中的关键知识点

简介: Seata 对业务无侵入是通过数据源代理实现的,数据源代理的实现涉及到 DataSource、Connection 以及 Statement,这几个关键知识属于 JDBC 的范畴
我是石页兄,朋友不因远而疏,高山不隔友谊情;偶遇美羊羊,我们互相鼓励

欢迎关注微信公众号「架构染色」交流和学习

背景

Seata 对业务无侵入是通过数据源代理实现的,从下图中可看出,数据源代理的实现涉及到 DataSource、Connection 以及 Statement,这几个关键知识属于 JDBC 的范畴,所以本篇从 JDBC 的视角对他们进行介绍。

image.png

一、JDBC 概述

JDBC 代表 Java 数据库连接。JDBC 是一种 Java API,用于连接数据库并执行查询。它是 JavaSE(Java 标准版)的一部分。JDBC API 使用 JDBC 驱动程序连接数据库。

image.png

在 JDBC 之前,ODBC API 是连接数据库并执行查询的数据库 API。但是,ODBC API 使用用 C 语言编写的 ODBC 驱动程序(即依赖于平台且不安全)。这就是为什么 Java 定义了自己的 API (JDBC API),它使用 JDBC 驱动程序(用 Java 语言编写)。当前的 JDBC 基于 X/Open SQL 调用级别接口。java.sql包包含 JDBC API 的类和接口。下面给出了 JDBC API 的流行接口列表:

  • Driver interface
  • Connection interface
  • Statement interface
  • PreparedStatement interface
  • CallableStatement interface
  • ResultSet interface
  • ResultSetMetaData interface
  • DatabaseMetaData interface
  • RowSet interface

我们可以使用 JDBC API 来使用 Java 程序处理数据库,使用 JDBC 操作数据源大致需要以下几个步骤:

  • 与数据源建立连接。
  • 执行 SQL 语句,检索 SQL 执行结果
  • 关闭连接。

二、与数据源建立链接

Connection 是 JDBC 对数据源连接的抽象,一旦建立了连接,使用 JDBC API 的应用程序就可以对目标数据源执行查询和更新操作。

image.png

获取Connection有两种途径

2.1 DriverManager

这是一个在 JDBC 1.0 规范中就已经存在、完全由 JDBC API 实现的驱动管理类。MYSQL5 之前需要Class.forName(“com.mysql.cj.jdbc.Driver”)的方式主动注册驱动。MYSQL5 之后的驱动包可以省略注册驱动的步骤,会自动加载 jar 包中 META-INF/services/java.sql.Driver 文件中的 JDBC 驱动类。通过getConnection获取数据库连接,如下:

Connection conn = DriverManager.getConnection(url,username,password);

2.2 DataSource:

DataSource 接口是 JDBC 2.0 API 中的新增内容,它提供了连接到数据源的另一种方法。使用 DataSource 对象是连接到数据源的首选方法。需要注意 JDBC API 中只提供了 DataSource 接口,DataSource 具体的实现由 JDBC 驱动程序提供。JDBC API 中定义了两个 DataSource 接口比较重要的扩展,用于支撑企业级应用。这两个接口分别为:

  • ConnectionPoolDataSource   * 支持缓存和复用Connection对象,主流的数据库连接池也提供了DataSource接口的具体实现,如Druid提供了 DruidDataSource,生产中我们会使用数据库连接池所提供的池化的Connection。连接池通过对连接的复用,而不是每次需要操作数据源时都新建一个物理连接来显著地提高程序的效率,这样能够在很大程度上提升应用性能和伸缩性
    image.png
  • XADataSource * 该实例返回的 Connection 对象能够支持分布式事务;如 Druid 中会提供DruidXADataSource。XAConnection 接口继承了 PooledConnection 接口,因此它具有所有 PooledConnection 的特性
    image.png

三、执行 sql、检索结果

3.1 创建Statement

获取到 JDBC 中的Connection对象之后,我们可以通过Connection对象设置事务属性,并且可以通过Connection接口中提供的方法创建StatementPreparedStatement或者CallableStatement对象。如:

java.sql.Connection#createStatement()

PreparedStatement和CallableStatement是Statement的子接口,Statement接口中定义了执行SQL语句的方法,但这些方法不支持参数输入。

  • PreparedStatement

    • 接口继承自Statement接口,增加了参数占位符功能,当执行SQL语句时,可使用“?”作为参数占位符,然后使用其提供的其他方法为占位符设置参数值。其实例对象包含已编译的 SQL 语句,由于已预编译过,所以其执行速度要快于 Statement 对象。因此,多次执行的 SQL 语句经常创建为 PreparedStatement 对象,以提高效率。(这里挖个坑,因为其参数设置机制,在实践中也可能会遇到其带来的问题)
  • CallableStatement

    • 接口继承自PreparedStatement接口,在PreparedStatement的基础上增加了调用存储过程并检索调用结果的功能。

3.2 执行 sql

Statement接口可以理解为 JDBC API 中提供的 SQL 语句的执行器,我们调用Statement接口中定义的不同方法以实现不同的结果:

  • 调用 executeQuery()方法执行查询操作
  • 调用 executeUpdate()方法执行更新操作
  • 调用 executeBatch()方法执行批量处理

3.3 获取结果

对结果的处理则:

  • 通过 getResultSet()方法来获取查询结果集,ResultSet 对象代表查询操作的结果集
  • 通过 ResultSet 对象的 getMetaData()方法获取结果集元数据信息,该方法返回一个 ResultSetMetaData 对象,我们可以通过 ResultSetMetaData 对象获取结果集中所有的字段名称、字段数量、字段数据类型等信息
  • 通过 getUpdateCount()方法来获取更新操作影响的行数

3.4 Connection、Statement、ResultSet 之间的关系

image.png

四 关闭 Connection 对象

当使用完 Connection 对象后,需要显式地关闭该对象。Connection 中的 close()方法用于关闭 Connection 对象,由该 Connection 对象创建的所有 Statement 对象也都会被关闭。连接池的实现的 close()方法中会把 Connection 回收到连接池中。

五、最后说一句

我是石页兄,如果这篇文章对您有帮助,或者有所启发的话,欢迎关注笔者的微信公众号【 架构染色 】进行交流和学习。您的支持是我坚持写作最大的动力。


参考并感谢

相关文章
|
26天前
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
27 0
|
3月前
sharding-jdbc 兼容 MybatisPlus的动态数据源
【8月更文挑战第2天】要使 `Sharding-JDBC` 与 `MyBatisPlus` 的动态数据源兼容,需引入相关依赖,配置数据源及分库分表策略,并在 `MyBatisPlus` 中设置参数以协同工作。可能还需自定义代码处理数据源切换。示例代码框架展示整合方式,实际应用中需按具体业务场景详细配置并处理异常情况,如数据一致性问题。
201 1
|
5月前
|
Apache 开发者
Apache Seata 如何解决 TCC 模式的幂等、悬挂和空回滚问题
【6月更文挑战第8天】Apache Seata 是一款分布式事务框架,解决TCC模式下的幂等、悬挂和空回滚问题。通过记录事务状态处理幂等,设置超时机制避免悬挂,明确标记Try操作成功来处理空回滚。Seata 提供丰富配置和管理功能,确保分布式事务的可靠性和效率,支持复杂事务处理场景,为企业业务发展提供支持。
200 7
|
5月前
|
SQL druid Java
JDBC、C3P0、DBCP、Druid 数据源连接池使用的对比总结.md2
JDBC、C3P0、DBCP、Druid 数据源连接池使用的对比总结.md
33 0
|
5月前
|
SQL druid Java
JDBC、C3P0、DBCP、Druid 数据源连接池使用的对比总结.md1
JDBC、C3P0、DBCP、Druid 数据源连接池使用的对比总结.md
51 0
|
6月前
|
设计模式 Java 数据库连接
【Spring源码】JDBC数据源访问实现
我们再来看看阅读线索三,这方面我们从设计模式进行入手。阅读线索三:从这个模块可以学到什么我们看下以下代码,PreparedStatement实例的是由PreparedStatementCreator实现的。再来看看PreparedStatementCreator接口,一共有三个子类实现。也就是说PreparedStatement的三种不同实现被封装到三个子类中,而具体需要哪种实现,只需要传入不同。
【Spring源码】JDBC数据源访问实现
|
6月前
|
消息中间件 Java 数据库连接
实时计算 Flink版产品使用合集之将sdkMode从rpc模式改为jdbc模式后,table.exec.mini-batch.enabled参数还生效吗
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
6月前
|
存储 Java Nacos
Seata常见问题之xa模式出现错误xid is not valid如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
185 4
|
6月前
|
NoSQL Java 数据库
Seata常见问题之xa模式下插入一条数据再更新这条数据会报错如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
183 2
|
6月前
|
Java 关系型数据库 微服务
Seata常见问题之项目一直启动不成功如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
507 0