前言
Spring实现事务学习笔记
Spring的事务的核心概念
当没有开启Spring的事务时,每一个数据层方法单独开启一个独立的事务。当开启了Spring的事务后,整个业务层方法作为一个新的事务,被调用的数据层方法将加入到业务层的事务中,组成一整个事务
- 事务管理员:业务层方法管理整个方法中出现的所有事务作为事务管理员
- 事务协调员:数据层方法将自己管理的事务作为事务协调员加入到事务管理员
启动用注解的方式进行事务管理
- 在Spring核心配置类上使用
@EnableTransactionManagement启用注解的方式进行事务管理
1 2 3
| @EnableTransactionManagement public class SpringConfig { }
|
添加配置类
- 定义一个事务管理器对象,并将事务管理器对象交给Spring容器管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.conf;
import com.alibaba.druid.pool.DruidDataSource; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
public class JDBCConfig {
@Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl(""); dataSource.setUsername(""); dataSource.setPassword(""); return dataSource; }
@Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(dataSource); return transactionManager; } }
|
添加注解
- 在需要添加事务处理的方法上添加
@Transactional注解
- 也可以写在类或接口上,被
@Transactional注解标注的类或接口中所有方法都会开启事务
@Transactional:开启事务
readOnly = true:设置为只读事务
timeout = -1:设置超时时间,-1标识用不超时
rollbackFor = {NullPointException.class}:设置事务遇到了指定异常进行回滚(类格式)
rollbackForClassName = "":设置事务遇到了指定异常进行回滚(字符串格式)
noRollbackFor = {NullPointException.class}:设置事务遇到了指定异常不进行回滚(类格式)
noRollbackForClassName = "":设置事务遇到了指定异常不进行回滚(字符串格式)
src/main/java/com/service/impl/UserServiceImpl.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;
@Service public interface UserService {
@Transactional void method();
}
|
- 此时,如果方法执行出现Error异常或运行时异常将会自动回滚,如果方法执行没有出现异常才会自动提交
设置事务的传播行为
@Transactional():开启事务
propagation = REQUIRED:设置事务的传播行为
| 传播属性 |
事务管理员 |
事务协调员 |
| REQUIRED(缺省值) |
如果开启了事务 |
则加入事务 |
| 如果没有开启事务 |
则新建事务 |
| REQUIRES_NEW |
如果开启了事务 |
则新建事务 |
| 如果没有开启事务 |
则新建事务 |
| SUPPORTS |
如果开启了事务 |
则加入事务 |
| 如果没有开启事务 |
则不开启事务 |
| NOT_SUPPORTED |
如果开启了事务 |
则不开启事务 |
| 如果没有开启事务 |
则不开启事务 |
| MANDATORY |
如果开启了事务 |
则加入事物 |
| 如果没有开启事务 |
则抛异常ERROR |
| NEVER |
如果开启了事务 |
则抛异常ERROR |
| 如果没有开启事务 |
则不开启事务 |
src/main/java/com/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.service;
import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;
@Service public class UserService {
@Transactional(propagation = REQUIRES_NEW) public void method() { try { ... } finally { ... } }
}
|
- 如果想要无论是否事务是否回滚都执行日志记录,可以将事务的传播行为设置为
@Transactional(propagation = REQUIRES_NEW),将业务代码写在try {}代码块,将日期记录代码写在finally {}代码块
完成
参考文献
哔哩哔哩——黑马程序员