背景
本节介绍了Spring对事务管理的支持,简化了数据库事务的配置。使得业务代码跟事务代码分离,实现解耦。
1.数据库事务基础知识
(1)何为数据库事务:
事务的思想是多条sql语句,要么所有执行成功,要么所有执行失败。
数据库事务必须同时满足4个特性:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)和持久性(Durabiliy),
简称为ACID。
原子性:表示组成一个事务的多个数据库操作是一个不可分割的原子单元;
一致性:事务操作成功后,数据库所处的状态和它的业务规则是一致的,即数据不会被破坏;
隔离性:在并发数据操作时,不同的事务拥有各自的数据空间,他们的操作不会对对方产生干扰。
持久性:一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中。
数据库管理系统采用数据库锁机制保证事务的隔离性。Oracle数据库还是用了数据版本的机制。
(2)数据并发问题:脏读、不可重复读、幻象读、第一类丢失更新和第二类丢失更新。在orical数据库中,不会发生
脏读的情况。
(3)数据库锁机制:按锁定的对象的不同,一般可以分为表锁定和行锁定;从并发事务锁定的关系上看,可以分为
共享锁和独占锁。
(4)事务隔离级别:用户指定会话的事务隔离级别,数据库就会分析事务中的sql语句,然后自动为事务操作的数据
资源添加适合的锁。数据库还会维护这些锁,当一个资源上的锁数目太多时,自动进行锁升级以提高系统的运行性能。
事务的隔离级别和数据库并发性是对立的。使用 READ UNCOMMITED隔离级别的数据库拥有最高的并发和吞吐量,
而使用SERIALIZABLE隔离级别的数据库并发性最低。
(5)JDBC对事务的支持:Connection默认情况下是自动提交的,即每条执行的sql语句都对应一个事务。
典型的jdbc事务数据操作代码:
Savepoint接口允许用户将事务分割为多个阶段,用户可以指定回滚到事务的特定保存点:
但是不是所有数据库都支持保存点功能。
2.ThreadLocal基础知识
模板类访问底层数据,根据持久化技术的不同,模板类需要绑定数据连接或会话的资源。但这些资源本身是非线程
安全的。我们使用ThreadLocal来解决这个问题。 通过ThreadLocal的类提供了对线程局部变量的支持。
(1)ThreadLocal是什么:是保存线程本地化对象的容器。当运行于多线程环境的某个对象使用ThreadLocal维护变量时,
ThreadLocal为每个使用该变量的线程分配一个独立的变量副本。
(2)ThreadLocal源码解析。
(3与Thread同步机制的比较:对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,访问串行化,对象
共享话;而ThreadLocal采用了“以空间换时间”的方式,访问并行化,对象独享化。前者仅提供一份变量,让不同的线程
排队访问;而后者为每个线程都提供了一份变量,因此可以同时访问而互不影响。
(4)Spring使用ThreadLocal解决线程安全问题:
用户可以根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有对象所访问的
同一ThreadLocal变量都是当前线程所绑定的。
3.Spring对事务管理的支持
Spring允许通过声明方式,在Ioc配置中制定事务的边界和事务属性,Spring自动在指定的事务边界上应用事务属性。
(1)事务管理关键抽象:
TransactionDefinition用于描述事务的隔离级别、超时时间、是否为只读事务和事务传播规则等控制事务具体行为的事务
属性。PlatformTransactionManager根据TransactionDefinition提供的事务属性配置信息创建事务,并用TransactionStatus
描述激活事务的状态。
(2)Spring的事务管理器实现类:
要实现事务管理,首先要在Spring中配置好相应的事务管理器,为事务管理器指定数据资源及一些其他事务管理控制属性。
(3)事务同步管理器:
Spring的事务同步管理器类 TransactionSyschronizationManager使用ThreadLocal为不同事务线程提供了独立的资源副本,
同时维护事务配置的属性和运行状态信息。不管用户使用的是编程式事务管理,还是声明式事务管理,都离不开
同步管理器。
Spring框架为不同的持久化技术提供了一套从TransactionSyschronizationManager中获取对应线程绑定资源的工具类:
通过这些方法可以获取和当前线程绑定的资源。
(4)事务传播行为:
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,他们规定了事务方法和事务方法发生嵌套
调用时事务如何进行传播。
4.编程式的事务管理
5.使用xml配置声明式事务
Spring的声明式事务管理是通过SpringAOP实现的,通过事务的声明性信息,Spring负责将事务管理增强逻辑动态
织入业务方法的相应连接点中。这些逻辑包括获取线程绑定资源、开始事务、提交/回滚事务、进行异常转换和处理
等工作。
(1)使用原始的TransactionProxyFactoryBean:不推荐用这个代理类进行配置。
(2)基于aop/tx命名空间的配置:
<tx:method>元素属性表:
6.使用注解配置声明式事务
(1)对业务类进行事务增强的标注:
因为注解本身具有一组普适性的默认事务属性,所以往往只要在需要事务管理的业务类中添加一个@Transaction注解。
因为注解只提供元数据,它本身并不能完成事务切面织入的功能,所以还需要在Spring配置文件中通过一行小小的配置
“通知”Spring容器对标注@Transaction注解的Bean进行加工处理。
(2)@Transactional注解属性说明:
(3)@Transactional注解可以被应用于接口定义和接口方法、类定义和类的public方法上。建议在业务实现类上使用@Transactional注解。
(4)在方法处的注解会覆盖类定义处的注解。
(5)可以使用不同的事务管理器。
(6)通过AspectJ LTW 引入事务切面。
7.集成特定的应用服务器
(1)BEA WebLogic
(2)WebSphere
总结
Spring的事务管理是Spring AOP技术的精彩应用的案例。 之前在学校学习数据库好像都没有涉及到事务管理,
在这一章算是补回来了,收获很多。