Spring框架(JavaEE开发进阶Ⅲ)—事务ACID、ThreadLocal

一、主要内容

1、事务ACID
2、ThreadLocal基础知识
3、理解Spring对事务管理的支持

二、前言

1、软件开发领域,全有或全无的操作被称为事务(transaction),确保数据或资源免于处在不一致的状态
2、事务是所有企业应用的核心
3、一个基于Web的应用系统具备了复杂的业务需求,在逻辑上分为三层结构:Web层、业务逻辑层、数据访问层。整个应用系统运行在同一个JVM中。这种架构中,事务管理属于业务逻辑层,通常在业务门面中划分。数据访问层参与事务过程,但不管理事务,在数据访问层的不同方法调用可以参与到一个事务过程中
4、事务管理也是横切关注点(需要分离),分离后的好处:业务对象划分抽象事务,无需关注事务涉及的数据库资源;数据访问对象获取接受事务管理的数据库资源,无需关注数据库资源如何加入事务
事务管理这个功能和业务逻辑功能是不直接相关的,是正交的,横切的
5、事务基础设施的目标在于让开发应用系统的程序员无需关注底层的事务处理,让数据访问对象仅包含实际的数据存取代码而不需要编写事务处理代码

三、事务ACID

1、事务四大特性ACID
2、原子性(Atomic)
1)事务是由一个或多个活动组成的一个工作单元
2)原子性确保事务中的所有操作全部发生或全部不发生
3、一致性(Consistent)
1)一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致性的状态,现实的数据不应该被损坏
4、隔离型(Isolated)
1)事务允许多个用户对相同的数据进行操作,每个用户的操作不会与其他用户纠缠在一起
2)事务应该被彼此隔离,避免同步读写相同数据的情况发生
5、持久性(Durable)
1)一旦事务完成,事务的结果应该持久化,这样能从任何的系统崩溃中恢复。这涉及到将结果存储到数据库或其它形式的持久化存储中

四、ThreadLocal基础知识

1、Spring通过各种模板降低了开发者使用各种数据持久技术的难度,这些模板类是线程安全的。使用模板类访问底层数据,根据不同的持久化技术,需要绑定数据连接或会话等资源,而这些资源本身是非线程安全的,资源池只是解决缓存问题
2、如对象是非线程安全的,在多线程环境下,对对象的访问应该采用synchronized进行同步,但模板类并未采用线程同步机制,因为同步会降低并发性,影响系统性能
3、ThreadLocal为解决多线程并发问题提供新的解决方案,Spring事务管理的底层技术离不开它
4、ThreadLocal是线程的一个本地化对象。当工作于多线程中的对象使用它维护变量时,ThreadLocal为每个使用该变量的线程分配一个独立的变量副本。从线程的角度看,这个变量就是线程的本地变量
5、ThreadLocal<T>类的方法:
void set(T value) 设置当前线程局部变量的值
T get() 返回当前线程所对应的线程局部变量
void remove() 删除当前线程局部变量,减少内存占用
void T initialValue() 返回该线程局部变量的初始值
6、ThreadLocal<T>类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键是线程对象,值对应线程的变量副本
7、ThreadLocal为每一个线程提供一个独立的变量副本,从而隔离了多个线程对访问数据的冲突
8、ThreadLocal提供了线程安全的对象封装,可以把不安全的变量封装进ThreadLocal
9、对于多线程资源共享问题,同步机制采用了“以时间换空间”方式;访问串行化,对象共享化;ThreadLocal采用了“以空间换时间”方式;访问并行化,对象独立化
10、Spring使用ThreadLocal解决线程安全问题
1)一般情况下,只有无状态的Bean才可以在多线程环境下共享(只能读不能写)
2)Spring中,大部分Bean声明为singleton作用域。Spring对一些Bean(RequestContextHolder、TransactionSynchronizationManager等)中非线程安全的“状态性对象”采用ThreadLocal进行封装,使其成为线程安全的,那么有状态的Bean就能以singleton的方式在多线程环境下共享使用了

五、理解Spring对事务管理的支持

1、Spring提供事务模板类TransactionTemplate,配合使用事务回调TransactionCallback指定具体的持久化操作就可以通过编程方式实现事务管理,而无需关注资源获取、复用、释放、事务同步和异常处理操作
2、Spring事务管理SPI(Service Provider Interface)的抽象层包含3个接口:
1)TransactionDefinition
定义Spring兼容的事务属性,对事务管理控制各方面进行配置
2)TransactionStatus
代表一个事务的具体运行状态
3)PlatformTransactionManager
属于Spring中SPI高层次事务抽象接口,定义3个方法:
TransactionStatus getTransaction(TransactionDefinition definition) 获得当前事务的具体状态
commit(TransactionStatus status) 提交事务
rollback(TransactionStatus status) 回滚事务
该接口的实现类就是特定事务框架的代理——事务管理器
3、Spring将JDBC的Connection、Hibernate的Session等访问数据库的连接或会话对象称为资源,这些资源不是线程安全的。为了让DAO、Service等类能成为singleton,Spring的事务同步管理器org.springframework.transaction.support.TransactionSynchronizationManager使用ThreadLocal为不同事务线程提供独立的资源副本,同时维护事务配置的属性和运行状态信息
4、Spring为不同的持久化技术提供一套从TransactionSynchronizationManager中获取对应线程绑定资源的工具类
5、当脱离模版类,手工操作底层持久技术的原生API时,就需要通过这些工具类获得线程绑定的资源,而不应该直接从DataSource或SessionFactory中获取,因为这样不能获得和本线程相关的资源,从而无法让数据操作参与到本线程相关的事务环境中
6、因此,TransactionSynchronizationManager将DAO、Service类中影响线程安全的所有“状态”统一抽取到该类中,并用ThreadLocal进行封装。这样,DAO对象(基于模版类或资源获取工具类创建)和Service对象(采用Spring事务管理机制)真正线程安全了
7、Spring提供对编码式和声明式事务管理的支持
8、Spring通过回调机制将实际的事务实现从事务性代码中抽象出来,Spring对事务的支持可以不需要JTA
9、如果应用中只使用一种持久化资源,Spring可以使用持久化机制本身所提供的事务支持,包括JDBC、Hibernate以及Java持久化API(JPA)
10、如果应用中事务跨多个资源(比如访问多个数据库),Spring使用第三方的JTA来支持分布式(XA)事务
11、编码式事务允许用户在代码中精确定义事务的边界
12、声明式事务(基于AOP)有助于将操作与事务规则进行解耦
13、Spring的声明式事务胜过EJB的容器管理事务CMT,允许声明额外的属性(例如隔离级别、超时)
14、选择编码式事务还是声明式事务很大程度上是在细粒度控制和易用性之间的权衡;通过编码实现事务控制,能精确控制事务边界,开始和结束完全取决于你的需求;一般应用中,不需要编码式事务提供的细粒度控制,而选择在上下文定义文件中声明事务


猜你喜欢

转载自blog.csdn.net/csj50/article/details/79846157
今日推荐