手写springboot事务注解@Transactional
事务的作用
保证数据的一致性原则 遵循acid
事务的分类
编程事务 (手动挡)
1、获取当前项目中的事务管理器
DataSourceTransactionManager
2、可以采取事务管理实现提交、回滚事务操作
举例
添加工具类
package com.jn.exam.eduservice.utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.stereotype.Component; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.interceptor.DefaultTransactionAttribute; /** * @author 江南大学1033190417 * @date 2022/2/2 22:20 */ @Component public class TransactionUtils { @Autowired private DataSourceTransactionManager dataSourceTransactionManager; /** * 开启事务 * @return */ public TransactionStatus begin(){ TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute()); return transaction; } /** * 提交事务 * @param transaction */ public void commit(TransactionStatus transaction){ dataSourceTransactionManager.commit(transaction); } /** * 回滚事务 * @param transaction */ public void rollback(TransactionStatus transaction){ dataSourceTransactionManager.rollback(transaction); } }
使用
@PostMapping("test")
@SuppressWarnings("all")//消除所有警告
public R test(Integer num){
TransactionStatus begin = null;
try {
begin= transactionUtils.begin();//开启事务
Student student=new Student();
student.setName("测试");
student.setNumber("1033190415");
student.setPassword(MD5Util.getMD5("123456"));
boolean save = studentService.save(student);
int a=10/num;
if (save) {
transactionUtils.commit(begin);//提交
return R.ok().message("添加成功");
}
}catch (Exception e){
e.printStackTrace();
transactionUtils.rollback(begin);//回滚
return R.error().message("添加失败");
}
return R.error().message("添加失败");
}
缺点:
代码重复,冗余
优点:
很好的扩展性
声明事务 (自动挡)
说明:声明事务实际上就是基于编程事务实现封装
只需要在方法上添加注解@Transactional
注意:@Transactional失效问题:不要try业务逻辑
为什么:如果try,Aop不会补货该异常,就不会回滚
如果非要try可以手动回滚
try { Student student=new Student(); student.setName("测试"); student.setNumber("1033190415"); student.setPassword(MD5Util.getMD5("123456")); boolean save = studentService.save(student); if (save) { return R.ok().message("添加成功"); } int a=10/num; }catch (Exception e){ e.printStackTrace(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚 return R.error().message("添加失败"); }
开始自定义注解
先自己建一个注解
package com.jn.exam.eduservice.utils; import java.lang.annotation.*; /** * @author 江南大学1033190417 * @date 2022/2/2 22:45 */ @Target({ElementType.METHOD,ElementType.TYPE})//注解可以用到类和方法上 @Retention(RetentionPolicy.RUNTIME)//生效时刻 @Inherited//说明子类可以继承父类中的该注解 @Documented//添加到注释文档 public @interface MyTransactional { }
定义一个Aop拦截方法或类上是否有@MyTransactional注解
package com.jn.exam.eduservice.utils; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.TransactionStatus; /** * 定义一个Aop拦截方法或类上是否有@MyTransactional注解 * * @author 江南大学1033190417 * @date 2022/2/2 22:51 */ @Component @Slf4j @Aspect public class ExTransactionAop { @Autowired private TransactionUtils transactionUtils; //环绕通知 @Around(value = "@annotation(com.jn.exam.eduservice.utils.MyTransactional)") public Object around(ProceedingJoinPoint joinPoint){ TransactionStatus begin=null; try { log.info("开启事务"); begin = transactionUtils.begin(); Object proceed = joinPoint.proceed();//目标方法执行 log.info("提交事务"); transactionUtils.commit(begin); return proceed; } catch (Throwable e) { e.printStackTrace(); log.error("回滚事务"); transactionUtils.rollback(begin); return "系统错误"; } } }

浙公网安备 33010602011771号