事务简介
- 事务:一系列操作,使数据库从一个状态转换到另一个状态,且保证要么全部成功要么全部失败。
- 事务满足 ACID 原则:
- 原子性:不可分割,要么全部成功,要么全部失败
- 一致性:从一个状态到另一个状态
- 隔离性:正确提交前,可能到结果不应显示给其他事务
- 持久性:提交后,永久保存在数据库中
Java事务
- 在Java编写的程序实现ACID操作,把数据库的增删改查的事务操作转移到Java代码中控制。
- Java事务机制和原理就是确保数据库操作的ACID特性。
Java事务实现模式
- Java事务类型
- JDBC事务:局限在一个数据库连接内。
- JTA(Java Transaction API)事务:与实现无关的,与协议无关的API。可跨多个数据库或多个DAO。
- 容器事务:应用服务器提供的。
Spring事务核心接口
imageSpring事务属性定义
事务属性
- 传播行为
int getPropagationBehavior()
- 隔离规则
int getIsolationLevel()
- 回滚规则
- 事务超时
int getTimeout()
- 是否只读?
boolean isReadOnly()
隔离规则
- 脏读:事务没提交,被提前读取。
- 不可重复读:两次读取数据不一致。
- 幻读:事务不是独立执行时发生的一种非预期现象。比如第一个事务修改表中数据全部为男的,第二个事务插入了一个女的,第一个事务再次读取全表发现怎么还有个女的。
事务隔离级别:定义了一个事务可能受其他并发事务影响的程度。
- ISOLATION_DEFAULT
- ISOLATION_READ_UNCOMMITTED 脏读,不可重复度,幻读
- ISOLATION_READ_COMMITTED 避免脏读,仍然会有不可重复读,幻读
- ISOLATION_REPEATABLE_READ 避免脏读,不可重复读,任然会有幻读
- ISOLATION_SERIALIZABLE 全部避免,也是最慢的
事务传播行为
- 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播;
- spring的7种传播行为:
- PROPAGATION_RREQUIRED 当前方法必须运行在事务中。如果不存在事务,则新启动一个事务
- PROPAGATION_RSUPPORTS 当前方法不需要事务上下文。如果存在事务则在事务中运行
- PROPAGATION_RMANDATORY 当前方法必须运行在事务中。如果不存在事务,则抛出异常
- PROPAGATION_RREQUIRED_NEW 当前方法必须运行在他自己的事务中,一个新事务会被启动。如果存在当前事务,在该方法执行期间会被挂起。
- PROPAGATION_RNOT_SUPPORTED 该方法不应该运行在事务中。如果存在事务,在该方法运行期间则被挂起。
- PROPAGATION_RNEVER 当前方法不应该运行在事务上下文。如果当前正有一个事务在运行,则会抛异常
- PROPAGATION_RNESTED 如果当前存在一个事务,则该方法会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独的提交或回滚。如果当前事务不存在,则和PROPAGATION_REQUIRED一样。
事务是否只读
- 利用数据库事务的“只读”属性,进行特定优化处理。
- 设置“只读”,注意数据库厂商的支持。Oracle的“readOnly”不起作用,MySQL的“readOnly”影响查询
事务超时
- 事务超时是一个定时器,在特定时间内完成,否则回滚。
- 设计事务的注意点:事务不能运行太长时间,否则占用太久资源
事务回滚
- 运行期异常才回滚,而检查型异常不会回滚
- 自定义回滚策略
- 遇到特定的检查型异常时像运行期异常一样回滚。
- 遇到特定的异常不回滚,即使是运行期异常。
事务状态
- 通过事务管理器获得TransactionStatus实例
- 控制事务回滚或提交时需要应用对应的事务状态
编程式事务管理概述
- 事务管理器方式 spring事务管理的三个接口
- 步骤:
- 获取事务管理器;创建事务属性对象
- 获取事务状态对象;创建JDBC模版对象
- 业务数据操作
- 步骤:
- 模版事务的方式(推荐) JdbcTemplate
- 步骤:
- 获取模版对象
- 选择事务结果类型
- 业务数据操作处理
- 步骤:
- 总结:
- 需要有效的数据源
- 创建编程事务管理对象
- 业务逻辑
声明式事务管理
- 基于AOP,对方法前后拦截
- 配置类型:tx拦截器;注解方式
- 实现方式:
- tx拦截器 使用XML配置
- 注解方式
事务管理最佳实践
- 编程式更精确自定义,声明式更解耦业务
- 小型,业务少,直观的的用编程式
- 大型,事务操作量,复杂的用声明式
- 事务管理器类型
- 不同数据源用不同的事务管理器
- 正确选择PlatformTransactionManager实现类
- 全局事务的选择JtaTransactionManager
- 不同数据源用不同的事务管理器
参考
- Spring事务管理,https://class.imooc.com/course/577
关于我:
linxinzhe,全栈工程师,目前供职于某500强通信企业。人工智能,区块链爱好者。
GitHub:https://github.com/linxinzhe
欢迎留言讨论,也欢迎关注我~
我也会关注你的哦!
网友评论