MyBatis DataSource和Transaction

本文探讨了MyBatis中DataSource和Transaction的重要角色。MyBatis提供了PooledDataSource和UnpooledDataSource实现,前者实现了简单的数据库连接池功能,依赖UnpooledDataSource创建连接。PooledConnection管理数据库连接,PoolState维护连接状态。对于事务,Mybatis有JdbcTransaction和ManagedTransaction两种实现,但通常结合Spring进行事务管理。

目录

DataSource

Transaction


在数据持久层,数据源和事务是两个非常重要的组件,对数据持久层的影响很大,在实际开发中,一般会使用Mybatis集成第三方数据源组件,如c3p0、Druid等,Mybatis也提供了自己的数据库连接池实现,本文会通过Mybatis的源码实现来了解数据库连接池的设计。事务方面,一般使用 Spring进行事务的管理,这里不做详细分析。下面我们看一下Mybatis是如何对这两部分进行封装的。

DataSource

常见的数据源都会实现javax.sql.DataSource接口,Mybatis中提供了两个该接口的实现类,分别是PooledDataSource和UnpooledDataSource,使用不同的工厂类分别管理这两个类的对象。

DataSourceFactory

DataSourceFactory系列类的设计比较简单,DataSourceFactory作为顶级接口,UnpooledDataSourceFactory实现了该接口,PooledDataSourceFactory又继承了 UnpooledDataSourceFactory。

public interface DataSourceFactory {

  // 设置 DataSource 的属性,一般紧跟在 DataSource 初始化之后
  void setProperties(Properties props);

  // 获取 DataSource对象
  DataSo
### 事务管理中的 `DataSource` 与 `EntityManager` 的区别 在 Java 企业级应用开发中,特别是在 Spring JPA 的上下文中,`DataSource` `EntityManager` 都是事务管理的重要组成部分,但它们在事务处理中的职责行为存在显著差异。 #### `DataSource` 事务的特性 `DataSource` 是 JDBC 层面的资源,它直接与数据库连接交互,负责获取管理数据库连接。在 Spring 中,可以通过 `PlatformTransactionManager` 接口的实现类(如 `DataSourceTransactionManager`)来管理基于 `DataSource` 的事务。这类事务适用于直接使用 JDBC、MyBatis 或其他不涉及 JPA 的场景。 事务的开启、提交回滚通过 `DataSourceTransactionManager` 控制,开发者需要手动管理连接的获取释放。例如: ```java @Autowired private DataSource dataSource; public void performJdbcOperation() { Connection conn = null; try { conn = dataSource.getConnection(); conn.setAutoCommit(false); // 执行 SQL 操作 // ... conn.commit(); } catch (SQLException e) { if (conn != null) { conn.rollback(); } } finally { if (conn != null) { conn.close(); } } } ``` 这种方式需要开发者对事务边界进行显式控制,适用于低层级的数据库操作。 #### `EntityManager` 事务的特性 `EntityManager` 是 JPA 提供的接口,用于管理实体对象的生命周期,并与事务管理器(如 `JpaTransactionManager`)配合完成事务控制。它封装了底层的数据库连接操作,并通过 `@Transactional` 注解实现声明式事务管理。 在 Spring Boot 中,通过配置 `JpaTransactionManager` 可以将事务与特定的 `DataSource` 关联,如以下配置所示: ```java @Bean(name = "test2TransactionManager") public JpaTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) { JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); jpaTransactionManager.setDataSource(dataSource); return jpaTransactionManager; } ``` 在业务代码中,通过 `@PersistenceContext` 注入 `EntityManager` 并使用 `@Transactional` 控制事务: ```java @Repository public abstract class BaseDao<T> { @PersistenceContext(unitName = "testUnit") protected EntityManager em; } @Service public class TutorialService { @Transactional public void updateTitle(Long id, String newTitle) { Tutorial tutorial = em.find(Tutorial.class, id); tutorial.setTitle(newTitle); em.merge(tutorial); } } ``` `EntityManager` 的事务管理是自动的,`@Transactional` 注解会触发事务的开启、提交或回滚,开发者无需手动管理连接事务边界。此外,`EntityManager` 还支持实体状态管理、延迟加载、缓存等高级特性。 #### 事务传播与生命周期管理 `DataSource` 事务的生命周期完全由开发者控制,包括连接的获取、提交释放。而 `EntityManager` 则在事务开始时自动绑定到当前线程,并在事务提交或回滚后自动关闭。这种机制称为“事务同步”(Transaction Synchronization),它确保了在同一事务中多个 `EntityManager` 调用共享同一个持久化上下文。 #### 事务边界与异常处理 在 `DataSource` 事务中,开发者必须手动处理异常并回滚事务,否则可能造成数据不一致。而在 `EntityManager` 事务中,`@Transactional` 注解会自动检测异常类型,并根据配置决定是否回滚。例如,默认情况下,只有在遇到未检查异常(`RuntimeException`)时才会回滚事务。 #### 总结 | 特性 | `DataSource` 事务 | `EntityManager` 事务 | |------|------------------|------------------------| | 底层实现 | JDBC | JPA | | 事务管理器 | `DataSourceTransactionManager` | `JpaTransactionManager` | | 事务控制方式 | 手动管理连接与事务边界 | 声明式事务(`@Transactional`) | | 实体管理 | 不支持实体状态管理 | 支持实体生命周期管理 | | 异常处理 | 需要手动回滚 | 自动回滚(可配置) | | 适用场景 | 简单的 JDBC 操作、MyBatis 等 | JPA 实体操作、复杂的业务逻辑 | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

骆驼整理说

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

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

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

打赏作者

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

抵扣说明:

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

余额充值