【笔记】Spring实现事务

前言

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.java
1
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.java
1
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 {}代码块

完成

参考文献

哔哩哔哩——黑马程序员