Spring的事务管理(二)
Spring事务管理目前有两种实现方式:声明式和编程式事务管理。
本文主要讨论的是,声明式事务管理方式,即借助Spring的AOP特性与@Transactional注解来实现。
@Transactional注解详解
事务管理的bean名称
@AliasFor(“transactionManager”)
String value() default “”;
事务管理的bean名称
@AliasFor(“value”)
String transactionManager() default “”;
事务的传播特性默认为REQUIRED
Propagation propagation() default Propagation.REQUIRED;
事务隔离级别默认为数据库的隔离级别
Isolation isolation() default Isolation.DEFAULT;
事务的超时时间
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
是否为只读事务 默认为false
boolean readOnly() default false;
事务运行时抛出哪些异常会回滚
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
事务运行时抛出哪些异常不会回滚
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
本文主要讲解的内容
本文主要讲解的内容为在事务的注解为默认值时,抛出异常后事务处理的方式:
异常的分类分为:编译期异常和运行时异常。本文也着重于从这两点来进行分析。本文使用的是springboot 2.0.0搭建的框架来进行验证的。首先我们在数据库创建表T1。有一个方法向该表中插入一条记录。下面我们分别看看两种异常,对事物的影响。
dao层代码如下
public interface CommonDao {
@Insert("INSERT INTO t2 (b,c,d) VALUES " +
"(#{b,jdbcType=VARCHAR},#{c,jdbcType=VARCHAR},#{d,jdbcType=VARCHAR})")
int insertT2(String b, String c, String d);
@Insert("INSERT INTO t1 (b,c,d) VALUES " +
"(#{b,jdbcType=INTEGER},#{c,jdbcType=INTEGER},#{d,jdbcType=INTEGER})")
int insertT1(int b, int c, int d);
}
运行时异常
首先有如下代码向数据库中插入一条记录service代码如下
@Service
public class CommonService {
@Autowired
private CommonDao commonDao;
@Transactional()
public void insertT1() throws Exception {
commonDao.insertT1(1, 2, 3);
throw new RuntimeException();
}
}
通过postman调用接口后,控制台看到如下结果:
2020-03-26 21:40:29.195 [DEBUG] [c.i.s.s.m.dao.CommonDao.insertT1] ==> Preparing: INSERT INTO t1 (b,c,d) VALUES (?,?,?)
2020-03-26 21:40:29.255 [DEBUG] [c.i.s.s.m.dao.CommonDao.insertT1] ==> Parameters: 1(Integer), 2(Integer), 3(Integer)
2020-03-26 21:40:29.328 [DEBUG] [c.i.s.s.m.dao.CommonDao.insertT1] <== Updates: 1
java.lang.RuntimeException
at com.it.sunflower.survey.miniprom.service.CommonService.insertT1(CommonService.java:20)
at com.it.sunflower.survey.miniprom.service.CommonService$$FastClassBySpringCGLIB$$bf79bb11.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at com.it.sunflower.survey.miniprom.service.CommonService$$EnhancerBySpringCGLIB$$ac069771.insertT1(<generated>)
at com.it.sunflower.survey.miniprom.controller.CommonController.common(CommonController.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl