Spring事务管理

来源:互联网 发布:教师网络研修日志 编辑:程序博客网 时间:2024/06/06 03:49

一、事务

    事务是指逻辑上的一组操作,这组操作要么全部成功要么全部失败。
    基本的特性:

A(原子性):事务是不可分隔的工作单位
C(一致性):事务前后数据完整性保持一致
I (隔离性):多个并发事务之间数据相互隔离
D(持久性):事务提交后对数据库中数据的改变是永久性的

二、Spring中的事务管理

    Spring支持两种方式的事务管理:编程式,声明式,在后面会写到。

    Spring事务管理高层抽象主要包括三个接口:

PlatformTransactionManager:事务管理器,真正管理事务的接口,包含提交回滚等
TransactionDefinition:事务定义信息,包含事务的隔离级别、超时、只读等信息
TransactionStatus:事务运行状态,是否已提交、新事务等状态

    以上三个接口彼此是相互联系的,Spring在进行事务管理的时候,会首先根据事务定义的信息如隔离级别传播行为等,然后由平台事务管理器来真正进行事务管理,在进行管理中事务会产生相应的状态保存在TransactionStatus中。

1. PlatformTransactionManager

    PlatformTransactionManage是个接口,有DataSourceTransactionManager,HibernateTransactionManager,JtaTransactionManager等实现类。

    Spring会为不同的持久层框架选择不同的PlatformTransactionManager接口实现,如MyBatis/SpringJDBC可以选择DataSourceTransactionManager,Hibernate可以选择HibernateTransactionManager。

2. TransactionDefinition

    TransactionDefinition提供了一组常量,定义了隔离级别,传播行为,超时信息,以及获取相应信息的方法。

    什么是传播行为?

这里写图片描述

    如上图所示
     一般业务调用一个login()或search()方法就能解决,其中每个方法对应于一个事务去完成。
    但可能出现一种复杂情况,需要调用AService中的方法和BService中的方法才能完成一个业务,那AService中的方法有一个事务,BService中也有,那么到底取哪个?

     而传播行为就是为了解决这个问题(业务层方法之间相互调用)。

PROPAGATION_REQUIRED
        支持当前事务,如果不存在就新建
        如login()方法中调用了search()方法,那么如果login()方法有事务就使用login()中的事务,如果没有那么在调用search()这个方法的时候search()就会创建一个事务把login()也包起来

PROPAGATION_SUPPORTS
        支持当前事务,如果不存在就不使用事务
        如login()中有事务那么search()就使用里面的事务,如果没有那么search()就不事务

PROPAGATION_MANDATORY
        支持当前事务,如果不存在则抛出异常

PROPAGATION_REQUIRES_NEW
        如果有事务则挂起当前事务,创建一个新的事务

PROPAGATION_NOT_SUPPORTED
        以非事务方式运行,如果有事务则挂起当前事务

PROPAGATION_NEVER
        以非事务方式运行,如果有实物则抛出异常

PROPAGATION_NESTED
        如果事务存在则嵌套事务执行
        如login()执行完成后设置一个保存点,在去执行search()后一起提交,如果search()出错可以设置为回滚login()或回到保存点。

3. TransactionStatus

    TransactionStatus提供了一系列方法,用来获取事务的状态如是否已经完成,是否有保存点,是否是新事务等。

三、编程式事务管理

    Spring对JDBC的基本操作进行了封装,形成JDBCTemplate,通常情况下,有三种方式得到JdbcTemplate 对象。

 1 、DAO 实现类中注入一个DataSource引用来编写代码完成JdbcTemplate 的实例化。

 2、在容器中配置一个JdbcTemplate Bean,注入DataSource后再把JdbcTemplate注入到DAO实现类。

 3、DAO实现类继承JdbcDaoSupport(Spring提供)后注入DataSource,这个类中定义了JdbcTemplate、DataSource属性,当设置DataSource 属性的时候,会创建jdbcTemplate 的实例。
这里写图片描述

    Spring为了简化编写的代码,提供了事务管理模板TransactionTemplate,哪个地方需要使用事务就在哪里注入这个模板。

    如下图所示,在进行事务管理时首先要配置事务管理器这个真正管理事务的对象,因为事务管理器操作事务需要获取连接,所以注入连接池对象。然后配置Spring提供的TransactionTemplate,但TransactionTemplate始终只是个模板,需要传入具体的事务管理器简化代码配置的一些操作。
    配置TransactionTemplate后再在业务层注入该TransactionTemplate即可。

这里写图片描述

    在业务实现类中执行TransactionTemplate的execute()方法中进行DAO相关操作,此方法就是调用 TransactionCallback 进行处理,TransactionCalback接口中定义了方法doInTransactionWithoutResult(),也就是需要在一个事务中做的事情都在这个方法中执行了,而这个doInTransaction 又传入了一个参数,TransactionStatus事务状态,可以通过该参数获取一些事务相关信息,或者调用回滚。

这里写图片描述

    以上就是编程式事务的大概流程。

四、声明式事务管理

    Spring的声明式事务管理其实就是基于AOP来实现的,在之前开启事务,之后提交或回滚事务。

1. 使用TransactionProxyFactoryBean

这里写图片描述

    在需要调用Service层方法时,就是用增强后的代理对象而不是原本的业务对象,在这个例子中getBean(“accountServiceProxy”);

    但这种方法不常用,因为需要为每个业务类配置事务增强。

2. 使用AspectJ的XML配置

这里写图片描述

3. 基于注解的方式

这里写图片描述

    然后在业务类上使用@Transactional注解即可!!

这里写图片描述

    无论哪种都需要配置事务管理器,毕竟这才是真正管理事务的类。

以上!

原创粉丝点击