Spring 事务管理
一、Java 事务导引
事务简介:
1. 什么是事务
事务是正确执行一系列的操作(或动作),使得数据库从一种状态转换成另一种状态,且保证操作全部成功,或者全部失败。
2. 事务原则是什么
事务必须服从 ISO/IEC 所指定的 ACID 原则。
ACID原则的具体内涵如下:
-
原子性(Atomicity):
即不可分割性,事务要么全部被执行,要么就全部不被执行。
-
一致性(Consistency):
事务的执行使得数据库从一种正确状态转换成另一种正确状态。
-
隔离性(Isolation):
在事务正确提交之前,它可能的结果不应显示给任何其他事务。
-
持久性(Durability):
事务正确提交后,其结果将永久保存在数据库中。
Java 事务
1. Java 事务的产生
程序操作数据库的需要。以 Java 编写的程序或系统,实现 ACID 的操作。
2. Java 事务实现
- 通过 JDBC 相应方法间接来实现对数据库的增删改查,把事务转移到Java程序代码中进行控制;
- 确保事务要么全部执行成功,要么撤销不执行。
总结:Java 事务机制和原理就是操作确保数据库操作的 ACID 特性。
3. Java 事务类型
- JDBC 事务:用 Connection 对象控制的手动模式和自动模式;
- JTA(Java Transaction API)事务:与实现无关的,与协议无关的 API;
- 容器事务:应用服务器提供的,且大多是基于 JTA 完成(通常基于 JNDI 的,相当复杂的 API 实现)
4. 三种事务的差异
- JDBC 事务:控制的局限性在一个数据库连接内,但是其使用简单。
- JTA 事务:功能强大,可跨越多个数据库或多 DAO,使用比较复杂。
- 容器事务:主要指的是 J2EE 应用服务器提供的事务管理,局限于 EJB 应用使用。
二、Spring 事务核心接口
Spring 事务管理器
1. JDBC 事务管理器(DataSourceTransactionManager)
本事务管理器是通过调用 java.sql.Connection
来管理事务。
2. Hibernate 事务管理器(HibernateTransactinManager)
本管理器将事务管理的职责委托给 ogr.hibernate.Transaction
对象来管理事务,而后者是从 Hibernate Session
中获取到的。
3. JPA 事务管理器(JpaTransactinManager)
通过一个 JPA 实体管理工厂(javax.persisitence.EntityManagerFactory 接口的任意实现)将与由工厂所产生的 JPA EntityManager合作来构建事务。
4. JTA 事务管理器(JtatransactionManager)
本管理器将事务管理的责任委托给 javax.transaction.UserTransactin
和 javax.transaction.TranasactionManager
对象进行事务管理。
Spring 事务属性
1. 事务属性范围:
2. 事务属性定义:
public interface TransactionDefinition {
// 返回事务的传播行为
int getPropagationBehavior();
// 返回事务的隔离级别,事务管理器根据它来控制
// 另一个事务可以看到本事务内的哪些数据
int getIsolationLevel();
// 返回事务必须在多少秒内完成
int getTimeout();
// 事务是否只读,事务管理器能够根据这个
// 对值进行优化,确保事务是只读的
boolean isReadOnly();
}
事务传播行为
当事务方法发被另一个事务方法调用时,必须指定事务应该如何传播。
Spring 的 7 种传播行为:
事务隔离级别
隔离级别定义了一个事务可能受其他并发事务影响的程度。
隔离级别分为:
事务中注意的问题
1. 事务是否只读:
利用数据库事务的“只读”属性,进行特定优化处理。
2. 注意:
事务的是否“只读” 属性,不同的数据库厂商支持不同
通常而言:只读属性的应用要参考厂商的具体支持说明,比如:
Oracle 的 "redaOnly" 不起作用,不影响其增删改查;
Mysql 的 "readOnly" 为 true, 只能查,增删改则出异常。
3. 事务超时:
事务超时就是事务的一个定时器,在特定时间内事务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束。
4. 设计事务时注意点:
为了使应用程序很好地运行,事务不能运行太长的时间。因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要的占用数据库资源。
5. 事务回滚:
默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚。
6. 自定义回滚策略:
- 声明事务在遇到的特定的检查型异常时像遇到运行期异常那样回滚;
- 声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。
Spring 事务状态
1. 事务接口
- 通过事务管理器获取 TransactionStatus 实例;
- 控制事务在回滚或提交的时候需要应用对应的事务状态;
- Spring 事务接口:
// Spring 事务状态接口
// 通过调用 PlatformTraansactionManager的getTransactin()
// 获取事务状态实例
public interface TransactionStatus {
boolean isNewTransaction(); // 是否是新的事务
boolean hasSavepoint(); // 是否有恢复点
void setRollbackOnly(); // 设置为只回滚
boolean isRollbackOnly(); // 是否为只回滚
boolean isCompleted; // 是否已完成
}
三、编程式事务管理
编程式事务实现方式
1. 模板事务(TransactionTemplate)的方法
此为 Spring 官方团队推荐的编程式事务管理方式;
主要工具为 JdbcTemplate 类。
2. 平台事务管理器(PlatformTransactionManager)方式
类似应用 JTA UserTransaction API 方式,但异常处理更简洁;
辅助类为:TransactionDefinition
和 TransactionStatus
。
编程式事务实现案例
1. 模板事务(TransactinTemplate)案例
步骤:
- 获取模板对象;
- 选择事务结果类型;
- 业务数据操作处理。
2. 平台事务管理器(PlatformTransactionManager) 案例
步骤:
- 获取事务管理器;
- 获取事务属性对象;
- 获取事务状态对象;
- 创建JDBC 模板对象
- 业务数据操作处理。
编程事务总结
需要有效的数据源,具体数据源根据实际情况创建。
创建编程事务管理对象
- 事务模板(TransactionTemplate)
- 事务管理器
业务逻辑处理:基于 JDBCTemplate 完成业务处理
四、声明式事务管理
声明式事务实现方式
1. 声明式事务管理的配置类型:
5种类型:
独立代理;共享代理;拦截器;tx 拦截器;全注释
五、事务管理最佳实践
编程事务管理和声明事务管理区别
1. 编程式事务允许用户在代码中精确定义事务的边界
2. 声明式事务有助于用户将操作与事务规则进行解耦
- 基于 AOP 交由 Spring 容器实现
- 实现关注点聚焦在业务逻辑上
3. 概况而言:
编程式事务侵入到了业务代码里面,但提供了更加详细的事务管理;
而声明式事务由于基于 AOP,所以既能起到事务管理的作用,又可以不影响业务代码的具体实现。
两种事务的选择
小型应用,事务操作少:
- 建议编程式事务管理实现:TransactionTemplate;
- 简单、显式操作、直观明显、可以设置事务名称。
大型应用,事务操作量多:
- 业务复杂度高、关联性紧密,建议声明式事务管理实现;
- 关注点聚焦到业务层面,实现业务和事务的解耦。
通用事务问题的解决方案
事务管理器类型
- 基于不同的数据源选择对应的事务管理器;
- 选择正确的
PlatfromTractionManager
实现类; - 全局事务的选择:
JtaTransactionManager
。
网友评论