阿里手册异常日志篇:【强制】有 try 块放到了事务代码中,catch 异常后,如果需要回滚事务,一定要注意手动回滚事务。
容易让人忽略的是:方法上未加任何属性的@Transactional注解只能在抛出RuntimeException或者Error时才会触发事务的回滚,常见的非RuntimeException是不会触发事务的回滚的。
避免失效有
1. 使用@Transactional(rollbackFor = Exception.class)注解,前提是不含有try{...}catch{...}捕获异常。
2. 使用@Transactional注解,不带任何属性,抛出@Transactional注解默认识别的RuntimeException
@Transactional
public String getUserInfo() {
try {
//do something
return "成功信息";
} catch (Exception e) {
e.printStackTrace();
//异常处理这里采用lombok
log.error("异常日志", e.getMessage());
//抛出异常
throw new RuntimeException();
}
}
弊端:非运行时异常不会回滚
3.使用@Transactional(rollbackFor = { Exception.class }),也能抛出捕获的非RuntimeException异常
@Transactional(rollbackFor = Exception.class)
public String uploadFile() throws IOException {
InputStream input = null;
try {
input = new FileInputStream("F:\\BaiduNetdiskDownload\\1.jpg");
int data = input.read();
while (data != -1) {
System.out.print((char) data);
data = input.read();
}
//do something
return "成功信息";
} catch (Exception e) {
e.printStackTrace();
//异常处理这里采用lombok
log.error("异常日志", e.getMessage());
//抛出所捕获的异常
throw e;
}
}
4.手动回滚
阿里规约硬性要求的
@Transactional
public String getUserInfo() {
try {
//do something
return "成功信息";
} catch (Exception e) {
e.printStackTrace();
//异常处理这里采用lombok
log.error("异常日志", e.getMessage());
//手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return "自定义异常信息";
}
}