基于springboot自定义事务注解
1.开启注解支持(springboot默认支持注解)
2.自定义注解接口
3.写事务类
4.写切面类
2.自定义注解接口
import java.lang.annotation.*;
@Target(ElementType.METHOD) //定义注解用在方法上
@Retention(RetentionPolicy.RUNTIME) //运行时注解
@Documented
public @interface CustomTransaction {
String value() default "";
}
3.写事务类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
@Component
@Scope(value = "prototype")
public class TransactionUtils {
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
public TransactionStatus init(){
System.out.println("创建事务了...");
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
return transactionStatus;
}
public void commit(TransactionStatus transactionStatus){
System.out.println("提交事务...");
dataSourceTransactionManager.commit(transactionStatus);
}
public void rollback(TransactionStatus transactionStatus){
System.out.println("事务回滚了....");
dataSourceTransactionManager.rollback(transactionStatus);
}
}
4.写切面类
import io.tianma.common.annotation.CustomTransaction;
import io.tianma.common.utils.TransactionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import java.lang.reflect.Method;
@Aspect
@Component
public class CustomTransactionAspect {
@Autowired
TransactionUtils transactionUtils;
@Pointcut("@annotation(io.tianma.common.annotation.CustomTransaction)")
public void transactionPointCut() {
}
@Around("transactionPointCut()")
public void around(ProceedingJoinPoint point){
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();//获取到方法对象
//获取到注解类
CustomTransaction annotation = method.getAnnotation(CustomTransaction.class);
if(annotation != null){
System.out.println(annotation.value());//打印注解上value的内容
}
//请求的类名以及方法名
String className = point.getTarget().getClass().getName();
String methodName = signature.getName();
System.out.println("执行的方法为:" + className + "." + methodName + "()");
//开启事务
TransactionStatus transactionStatus = transactionUtils.init();
try {
//执行方法
point.proceed();
//执行成功提交事务
transactionUtils.commit(transactionStatus);
} catch (Throwable throwable) {
//执行方法出错则回滚事务
transactionUtils.rollback(transactionStatus);
}
}
}
5.项目service
@Override
@CustomTransaction("新增用户开启事务")
public void saveUser() {
SysUserEntity user = new SysUserEntity();
user.setUserId("D123456");
user.setName("张三");
user.setCreateUserId("D123456");
user.setCreateTime(new Date());
this.save(user);
// System.out.println(1/0);
SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity();
sysUserRoleEntity.setRoleId(123456L);
sysUserRoleEntity.setUserId("123456");
sysUserRoleService.save(sysUserRoleEntity);
}
6.先查询数据库
查询数据库没有数据
7. 调用api
可以看出控制台已经执行成功
再查询一次数据库
可以看到已经有一条记录产生,并且切面也已经执行了
8.打开注释(System.out.println(1/0)),并且将user_id改为D1234567
SysUserEntity user = new SysUserEntity();
user.setUserId("D1234567");
user.setName("张三");
user.setCreateUserId("D1234567");
user.setCreateTime(new Date());
this.save(user);
System.out.println(1/0);
SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity();
sysUserRoleEntity.setRoleId(1234567L);
sysUserRoleEntity.setUserId("1234567");
sysUserRoleService.save(sysUserRoleEntity);
可以看出事务进行回滚了,再查询一次数据库
可以看到报错后事务并没有进行提交,而是进行了回滚
结尾
自此基于springboot的自定义事务注解已完成