Spring事务的配置
- Spring事务的配置
- 声明式事务管理-xml方式配置
- 准备配置文件
- 配置事物管理器-DataSourceTransactionManager
- 事物方法的属性细节配置
- 声明式事务管理-基于注解配置
- applicationContext.xml配置文件
- AccountServiceImpl 业务层代码
- 事物配置的注解和XML配置的选择
- 小结
- Spring 核心作用
- 核心功能
Spring事务的配置
Spring支持编程式事务管理和声明式事务管理。
- 编程式事务管理:事务和业务代码耦合度太高。
- 声明式事务管理:侵入性小,把事务从业务代码中抽离出来,使用AOP配置到配置文件中,提高维护性。
声明式事务管理-xml方式配置
准备配置文件
在配置文件中引入新的命名空间 tx
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
配置事物管理器-DataSourceTransactionManager
Spring对象事务的支持,必须先配置事务管理器,事务管理器已经封装了事务的具体的处理
DataSourceTransactionManager
使用JDBC,MyBatis的事务管理器;(当前案例使用的Spring的JDBC操作,所以配置这个)
<!-- 1,配置事务管理器(应根据情况使用合适的事务管理器) -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--
1、切入点(Pointcut):在哪些类,哪些方法上切入(where);
2、增强(Advice):早期翻译为通知,在方法执行的什么时机(when:方法前/方法后/方法前后)做什么(what:增强的功能);
3、切面(Aspect):切面=切入点+通知,通俗点就是:什么时机,什么地点,做什么!
4、织入(Weaving):把切面加入到对象,并创建出代理对象的过程。(该过程由Spring来完成)。
WWW 原则 :
where : 在什么地方切事务
what : 干什么(切事务)
when : 时机(在方法前或者后)
-->
<!-- 事务相关的配置 : 使用AOP面向切面编程(切事务) : 使用 tx: 标签 -->
<!-- tx:advice : 配置事物的标签
id : 唯一标识
transaction-manager : 需要用到的事物管理器
-->
<!-- 2,配置管理事务的“增强” :环绕通知-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- 配置要切的方法 : trans (默认使用的是环绕通知) -->
<tx:method name="trans"/>
</tx:attributes>
</tx:advice>
<!-- 3,面向切面 : -->
<aop:config >
<!-- 切入点 : where -->
<aop:pointcut expression="execution ( * cn.xc.spring.service..*.*(..))" id="pt"/>
<!-- 配置切面 切面 = 切入点 + 通知
advice-ref 通知的引用
pointcut-ref 切入点的引入
-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt" />
<!-- 织入(Weaving):把切面加入到对象,并创建出代理对象的过程。(该过程由Spring来完成) -->
</aop:config>
事物方法的属性细节配置
事务方法属性:
事务方法属性 | 描述 |
name | 匹配到的方法模式 |
read-only | 如果为true,开启一个只读事务,只读事务的性能较高,但是不能再只读事务中,使用DML |
isolation | 代表数据库事务隔离级别(就使用默认) DEFAULT:让spring使用数据库默认的事务隔离级别; |
no-rollback-for | 如果遇到的异常是匹配的异常类型,就不回滚事务 |
rollback-for | 如果遇到的异常是指定匹配的异常类型,才回滚事务;spring默认情况下,spring只会去回滚RuntimeException及其子类,不会回滚Exception和Thowable |
propagation | 事务的传播方式(当一个方法已经在一个开启的事务当中了,应该怎么处理自身的事务) 1,REQUIRED(默认的传播属性):如果当前方法运行在一个没有事务环境的情况下,则开启一个新的事务,如果当前方法运行在一个已经开启了的事务里面,把自己加入到开启的那个事务中 2,REQUIRES_NEW:不管当前方法是否运行在一个事务空间之内,都要开启自己的事务 |
timeout | 事务处理的超时时间,默认事物管理自动处理 ,可以手动配置 |
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- <tx:method>
name : 需要切面的方法
isolation : 事务的隔离级别 DEFAULT 使用当前数据库默认的隔离级别,不同数据库隔离级别不同(可以不配置)
propagation : 事物的传播规则 ,默认使用 REQUIRED
read-only : 是否是只读事务, DQL配置即可
-->
<!-- 一般DML操作才需要事务,DQL查询操作是不需要事物
* 通配符
-->
<!-- 所有以前缀开都的方法都认为是 查询方法,就不切入事物 -->
<tx:method name="get*" read-only="true"/>
<tx:method name="select*" read-only="true" />
<tx:method name="find*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="list*" read-only="true"/>
<!-- 非查询(DQL)方法: DML操作,需要事务管理 -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
声明式事务管理-基于注解配置
Spring的声明式事务也支持 注解
applicationContext.xml配置文件
<!-- 1,配置事务管理器(应根据情况使用合适的事务管理器) -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入dataSource -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启注解驱动配置事务
编写此标签:Spring底层就支持注解配置事物,并且已经配置好事物管理器
-->
<tx:annotation-driven transaction-manager="txManager"/>
AccountServiceImpl 业务层代码
@Service
/* @Transactional
* 贴上此当前类已经被Spring事务管理
* 注意: @Transactional 只能对当前贴的Service类有效
* 常用属性 :
* isolation=Isolation.REPEATABLE_READ, 隔离级别
propagation=Propagation.REQUIRED,传播规则
readOnly=true 是否只读事务
*
*/@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
public class AccountServiceImpl implements AccountService{
@Autowired
private AccountDao dao;
public void trans(Integer transOutId,
Integer transInId, Integer money) {
dao.tranOut(transOutId, money);
System.out.println(1 / 0);// 模拟断电
dao.tranIn(transInId, money);
}
//单独为某一个方法配置具体的事物细节:如查询方法,事物是只读的
@Transactional(readOnly=true)
public Object getUser() {
//查询操作
return null;
}
@Transactional(readOnly=true)
public List<Object> getUsers() {
//查询操作
return null;
}
}
事物配置的注解和XML配置的选择
Xml配置 : 代码清晰,配置量少,容易维护
注解配置 : 侵入代码,每个Service层类都得配置,针对不同的方法还得配置事务细节:如查询方法配置只读操作,不容易维护
建议选择xml配置
小结
Spring框架出现原因?
早期企业级开发组件(框架) EJB (重量级)不好用
音乐博士,计算机大牛
觉得ejb 不好,写了一本书各种吐槽抨击 ejb
顺便写了一个轻量级 一站式 企业框架 spring
Spring 核心作用
解耦 (降低程序代码与代码的直接依赖关系)
核心功能
Spring容器-下面所有操作都在Spring 容器中完成,Spring就是项目对象的管家
- IOC :控制反转(将对象的创建权交给Spring管理)
(1) Xml 配置
① <bean id/name=’xxx’ class = “类的全限定名” scope=’作用范围’ init-mehtod=’初始化方法’destory-mehtod=’销毁方法’>
② 从Spring容器中读取bean对象
(2) 注解配置 -贴在类上即可
① @Component 通用组件扫描创建
② @Controller 表现层(SpringMVC 专用)
③ @Service 业务层专用
④ @Repository 持久层/DAO/Mapper 专用
⑤ @Scope 作用范围
⑥ @PostConstrcut 初始化方法
⑦ @PreDestory 销毁方法 - DI : 依赖注入(将对象的属性赋值,对象依赖关系维护交给Spring)
(1) XML配置
① <property name=’’ value/ref=’’> 属性注入
② <constructor-arg name=’参数名’ value/ref=’’ >
③ A.P 命名空间
③ B.<bean id =’xx’ class =”Xxxx” p:属性名=’值’ p:属性名-ref=’引用类型’>
(2) 注解配置
① Spring框架制定
A. @Autowired 默认按照类型注入
a. 可以贴在 字段(成员编写),set方法,构造函数
B. @Qualifier 从多个相同类型中通过id指定唯一的那个bean
② JavaEE 官方指定
A. @Resource(name=’bean的id’) - AOP :面向切面编程
(1) AOP 底层原理-Java动态代理
① JDK动态代理 : 只能有接口的类型进行代理
② CGLIB代理 :即可代理有接口类,有可以代理没有接口的
(2) 专业术语
① JoinPoint 连接点(方法)
② PointCut 切入点 (某一类方法,规则)
③ Advice 通知/增强
④ Aspect 切面 = 切入点+通知
⑤ Weaving 织入(Spring自动完成) - Spring事务管理
(1) 配置事务管理器
① JDBC/MyBatis ---->DataSourceTransactionManager
(2) 事务的隔离级别 4个
(3) 事务的传播规则(行为) 7个
(4) 是否是只读事务
(5) 使用AOP 将事务切入到 业务层 - Spring-Jdbc (了解)
(1) jdbcTemplate 模板类
① Update 更新方法(update,insert,delete)
② queryForObject : 单行查询
③ Query : 多行查询 - Spring-test
- SpringMVC