spring 事务笔记(四)
spring 事务原理简述
之前用spring事务都是直接用注解的方式,后来去试试用xml配置这种,其实这两种都是声明式的事务。spring的事务都是通过AOP实现的,说白了就是在用AOP前置通知加个对数据连接设置为非自动提交(默认自动提交),然后在用个AOP的返回通知做个自动提交,事务就这样实现了。
声明式事务
1. 注解方式
配置事务管理器
因为要用spring的事务,就需要在spring上下文中注册一个DataSourceTransactionManager,这个事务管理者主要做数据库事务。
@Configuration
public class DataSourceConfig {
@Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
public DataSource dataSource(){
....
return dataSource;
}
}
开启事务并使用
使用是十分简单的,之前我在自己的另一个博客中有写过:(1条消息) spring事务(三)_鸭梨的药丸哥的博客-CSDN博客,这里就直接拷过来了。
开启事务管理功能: @EnableTransactionManagement
事务注解: @Transactional
@Transactional的属性
- name 属性指定选择哪个事务管理器。
- propagation 事务的传播行为,默认值为 REQUIRED。
- isolation 事务的隔离度,默认值采用 DEFAULT。
- timeout 事务的超时时间,默认值为-1。
- read-only 指定事务是否为只读事务,默认值为 false;
- rollback-for 用于指定能够触发事务回滚的异常类型
- no-rollback- for 抛出 no-rollback-for 指定的异常类型,不回滚事务。
事务的隔离度
刚好对应数据库的几个隔离级别,默认是DEFAULT(数据库启用的隔离级别)
@Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据
@Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据
@Transactional(isolation = Isolation.REPEATABLE_READ):可重复读
@Transactional(isolation = Isolation.SERIALIZABLE):串行化
2.xml配置方式
配置事务管理器
一个数据源,一个transactionManager,没什么好说的。
<bean id="dataSource"
class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/User?useSSL=true" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
配置事务切入点
配一个切点和一个通知,因为这个是事务通知,所以我们引用的是spring事务提供的transactionManager,然后通过tx:attributes去定义要匹配的方法,对匹配的方法定义一些等级即可。
<!-- 开启aop注解支持 -->
<aop:aspectj-autoproxy/>
<aop:config>
<aop:pointcut id="Admincut" expression="execution(* com.wenyao.serviceImpl.AdminServiceImpl.*())"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="Admincut"></aop:advisor>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 匹配查询的方法 -->
<tx:method name="get*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="count*" read-only="true"/>
<!-- 匹配增删改方法 事务行为,事务的隔离度-->
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
method name="add*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>