事务控制方式
案例介绍
- 银行转账业务说明
- 银行转账操作中,涉及到从A账户到B账户的资金转移操作。数据层仅提供单条数据的基础操作,未涉及多账户间的业务操作。
新建7个文件
内容如下 运行可见结果
编程式事务
在AccountServiceImpl里添加如下语句 在applicationContext.xml里添加这个 运行可见报错 此时事务进行了回滚,数据库的值没有变化
- 使用spring提供的专用于mybatis的事务管理器在业务层硬编码进行事务管理
- 业务层要注入dataSource对象
使用AOP控制事务
- 将业务层的事务处理功能抽取出来制作成AOP通知,利用环绕通知运行期间动态织入
各文件内容 新建TxAdvice 内容 pom文件导入依赖 applicationContext文件 文件头部内容
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
运行可见数据库内容变化
- 将业务层的事务处理功能抽取出来制作成AOP通知,利用环绕通知运行期动态织入
步骤:
- 配置AOP通知类,并注入dataSource
- 使用环绕通知将通知类织入到原始业务对象执行过程中
小节
- 基于AOP思想,抽取通知功能,利用环绕通知动态注入
声明式事务(XML)
在applicationContext里新添头
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
aop:advice与aop:advisor区别
- aop:advice配置的通知类可以是普通的java对象,不实现接口,也不使用继承关系
- aop:advisor配置的通知类必须实现通知接口
- MethodBeforeAdvice
- AfterReturningAdvice
- ThrowsAdvice
- …
tx配置
- 名称:tx:advice
- 类型:标签
- 归属:beans标签
- 作用:专用于声明事务通知
- 格式
<beans>
<tx:advice id="txAdvice" transaction-manager="txManager">
</tx:advice>
</beans>
- 基本属性:
- id:用于配置aop时指定通知器的id
- transaction-manager:指定事务管理器bean
tx:method属性
<tx:method
name="*"
read-only="false"
timeout="-1"
isolation=DEFAULT"
no-rollback-for=""
rollback-for=""
propagetion="REQUIRED"
/>
- name:待添加事务的方法名表达式(支持*号通配)
- read-only:设置事务的读写属性,true为只读,false为读写
- timeout:设置事务超时时长,单位秒
- isolation:设置事务隔离级别,该隔离级设定是基于Spring的设定,非数据库端
- no-rollback-for:设置事务中不回滚的异常,多个异常间使用,号分割
- rollback-for:设置事务中必回滚的异常,多个异常间使用,号分割
- propagation:设置事务的传播行为
- 声明式事务的配置方式
- 设定事务管理器
- 专用事务通知器
- AOP配置切面,使用通知器绑定切入点
事务传播行为
- 事务管理员
- 事务协调员
- 事务传播行为修饰的是协调员针对管理员所携带事务的态度
- 企业开发过程中,发现同属于同一个事务控制的各个业务中,如果某个业务与其他业务隔离度较高,拥有差异化的数据业务控制情况,通常使用事务传播行对其进行控制
声明式事务(注解)
首先把applicationContext.xml里的选中代码删掉 新添此句 在AccountServiceImpl里新添@Transactional注解 可以在注解里添加属性
- 名称:@Transactional
- 类型:方法注解,类注解,接口注解
- 位置:方法定义上方,类定义上方,接口定义上方
- 作用:设置当前类/接口中所有方法或具体方法开启事务,并指定相关事务属性
- 范例:
@Transactional(
readOnly = false,
timeout = -1,
isolation = Isolation.DEFAULT,
rollbackFor = {},
noRollbackFor = {},
propagation = Propagation.REQUIRED
)
常用方法是将该注解写在接口方法上,也可以配置在接口上
- 名称:tx:annotation-driven
- 类型:标签
- 归属:beans标签
- 作用:开启事务注解驱动,并指定对应的事务管理器
- 范例:
<tx:annotation-driven transaction-manager="txManager"/>
- 声明式事务注解方式
- 开启注解驱动
- 配置事务属性(@Transactional)
声明式事务(纯注解驱动)
在AccountDao里新添@Update注解
删除AccountDao.xml 实现类新增两个注解 新增三个文件
此时可以删除xml文件直接正常运行了
- 名称:@EnableTransactionManagement
- 类型:类注解
- 位置:Spring注解配置类上方
- 作用:开启注解驱动,等同XML格式中注解驱动
- 范例:
@Configuration
@ComponentScan("com.thenema.bank")
@PropertySource("classpath:jdbc.properties")
@Import({JDBCConfig.class,MyBatisConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
@Bean
public PlatformTransactionManager getPlatformTransactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
|