【spring学习笔记五】spring事务管理

来源:互联网 发布:淘宝搬家到微店 编辑:程序博客网 时间:2024/06/05 01:01

概念部分

事务特性:spring封装了事务管理(打开事务,提交事务,回滚事务)的代码,因为在不同平台操作事务的代码各不相同,所以spring提供了一个接口PlatformTransactionManager(事务管理器),接口中封装了事务的操作方法。针对不同的平台该接口给出了不同的实现类。分别为DataSourceTransactionManager和HibernateTransactionManage实现类。

l DataSourceTransactionManager针对JdbcTemplate、MyBatis 事务控制,使用Connection(连接)进行事务控制:

开启事务 connection.setAutoCommit(false);

提交事务 connection.commit();

回滚事务 connection.rollback();

l HibernateTransactionManage针对Hibernate框架进行事务管理, 使用Session的Transaction相关操作进行事务控制:

开启事务session.beginTransaction();

提交事务session.getTransaction().commit();

回滚事务session.getTransaction().rollback();

学习spring事务最核心的就是要知道操作事务的核心对象是PlatformTransactionManager,但是该接口不需要自己写,由spring提供。

spring管理事务的属性介绍:

事务的隔离级别:1.读未提交 2.读已提交  4.可重复读  8.串行化

事务是否只读(true false)

事务的传播行为:事务传播行为用于解决两个被事务管理的方法互相调用问题,给属性只存在业务层之间平行调用时。


在实际企业开发中,大部分都使用PROPAGATION_REQUIRED(默认值)

演示事务的环境准备(模拟转账场景)

1.建立工程,导包(包和之前的学习笔记中的包一样)。


2.建立数据库


3.写AccountDao及实现类



4.业务层AccountService以及实现类


5.写配置文件applicationContext。编写配置文件时了解各个对象之间的依赖关系,在本次例子中,datasource依赖jdbctemplate,由于jdbctemplaat继承了JdbcDaoSupport直接获取,因此不用注入到容器中管理,datasource--》AcountDao-->AccountService



6.编写测试类



7.如果不加入事务管理的话,在业务层写个问题程序导致转账过程出错,之后钱的总额发生了改变,因此需要添加事务管理才能正常进行业务操作。


3种方式给service层添加事务管理(编码式,xml配置(aop),注解配置(aop))

在企业中不用编码式,全部是用xml或者注解配置进行事务管理。因此只讲解如何使用xml配置和注解配置。

springAop准备一个事务通知,目标对象AccountService,所以我们只需要配置进行织入就OK了。

在上面例子的基础上进行导包,既然是aop,所以要导入aop相关的jar包,然后添加新的约束(tx)。bean(最基本的),context(注解或者读取porperties配置文件),aop(配置aop),tx(配置事务通知)


xml(aop)配置

上面目标对象(accountService)有了,现在开始配置事务通知。

applicationContext.xml文件

<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd "><!--事务核心管理器,封装了所有事务操作,依赖于连接池--><bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">      <property name="dataSource" ref="dataSource" />  </bean> <!-- 配置事务通知 --><tx:advice id="transactionManagerAdivice" transaction-manager="transactionManager" ><tx:attributes><!-- 以方法为单位,指定方法应用什么事务属性isolation:隔离级别propagation:传播行为read-only:是否只读 --><tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /><tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" /><tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" /><tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" /></tx:attributes></tx:advice><!-- 配置织入 --><aop:config ><!-- 配置切点表达式 --><aop:pointcut expression="execution(* com.service.*ServiceImpl.*(..))" id="txPc"/><!-- 配置切面 : 通知+切点 advice-ref:通知的名称 pointcut-ref:切点的名称 --><aop:advisor advice-ref="transactionManagerAdivice" pointcut-ref="txPc" /></aop:config><!-- 连接池 --><context:property-placeholder location="classpath:db.properties"/><bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driverClass}"></property><property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property><property name="user" value="${jdbc.user}"></property><property name="password" value="${jdbc.password}"></property></bean><!-- dao --><bean name="accountDao" class="com.dao.AccountDaoImpl"><property name="dataSource" ref="dataSource"></property></bean> <!-- service --><bean name="accountService" class="com.service.AccountServiceImpl"> <!-- <property name="ad" ref="accountDao"></property>  --></bean></beans>
编写测试类后发现加入事务管理后即使业务层程序异常也不会导致数据库错误,事务管理会自动回滚,保持数据库总金额不变。

注解配置(aop)

导包和之前xml配置一样,去掉之前配置文件中编写通知和切面,改为开启注解通知,即可在文件中使用注解管理事务:

在使用事务管理的方法上加上注解即可,在开发中可以把注解写在类名上面,对类里面的所有方法进行事务管理。

@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)