事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编程式和声明式的两种方式。编程式事务指的是通过编码方式实现事务;声明式事务基于 AOP,将具体业务逻辑与事务处理解耦。声明式事务管理使业务代码逻辑不受污染, 因此在实际使用中声明式事务用的比较多。声明式事务有两种方式,一种是在配置文件(xml)中做相关的事务规则声明,另一种是基于 @Transactional 注解的方式。这里将着重介绍基于 @Transactional 注解的事务管理。有两个注意点:
- 默认配置下 Spring 只会回滚运行时、未检查异常(继承自 RuntimeException 的异常)或者 Error。
- @Transactional 注解只能应用到 public 方法才有效。
项目的DEMO代码:https://github.com/heyu52/-spring-cloud 我们依然上使用上节课的代码来进行事务的开发测试。
简单的使用方法
只需在方法加上 @Transactional 注解就可以了。我们对CreateUser进行一定的修改,让它报一个异常
@Transactional(propagation = Propagation.REQUIRED)
@RequestMapping("/CreateUser")
public int CreateUser() {
int k = 0;user);
if (true) {
throw new RuntimeException("我报错了");
}
return k;
}
运行项目,打开网址:http://127.0.0.1:8080/CreateUser
我们去查询数库,发现数据确实没有保存进数据库。对于使用过NET 的同学来说,这实在是简单得有点过分了。
特定异常回滚
我们先自定义一个异常类
package com.example.demo.demo.Common;
public class MyException extends Exception {
}
接口新增方法
void saveThenRollback(User user) throws MyException;
实现方法
@Override
@Transactional(rollbackFor = MyException.class)
public void saveThenRollback(User user) throws MyException {
int k = jdbcTemplate.update("INSERT INTO user(name, sex, age) values(?, ?, ?)",
user.getName(), user.getSex(), user.getAge());
throw new MyException();
}
调用方法
@RequestMapping("/saveThenRollback")
public int saveThenRollback() {
int k =
try {
userRepository.saveThenRollback(user);
} catch (MyException e) {
System.out.println("不好意思,我错了");
}
return k;
}
运行测试,打开网址:http://127.0.0.1:8080/saveThenRollback
我们去查询数库,发现数据确实没有保存进数据库。
@Transactional 注解的属性介绍
value 和 transactionManager 属性
它们两个是一样的意思。当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器。
propagation 属性
事务的传播行为,默认值为 Propagation.REQUIRED。
可选的值有:
- Propagation.REQUIRED 如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。
- Propagation.SUPPORTS 如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。
- Propagation.MANDATORY 如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。
- Propagation.REQUIRES_NEW 重新创建一个新的事务,如果当前存在事务,暂停当前的事务。
- Propagation.NOT_SUPPORTED 以非事务的方式运行,如果当前存在事务,暂停当前的事务。
- Propagation.NEVER 以非事务的方式运行,如果当前存在事务,则抛出异常。
- Propagation.NESTED 和 Propagation.REQUIRED 效果一样。
isolation 属性
事务的隔离级别,默认值为 Isolation.DEFAULT。
可选的值有:
- Isolation.DEFAULT 使用底层数据库默认的隔离级别。
- Isolation.READ_UNCOMMITTED
- Isolation.READ_COMMITTED
- Isolation.REPEATABLE_READ
- Isolation.SERIALIZABLE
timeout 属性
事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly 属性
指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollbackFor 属性
用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
noRollbackFor 属性
抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。