导入aop
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
可以复制用
package org.mallOnline.admin.config;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;
@Aspect
@Configuration
public class TransactionAdviceConfig {
//*后面要有空格
private static final String AOP_POINTCUT_EXPRESSION = "execution (* org.mallOnline.admin.service.*.*(..))";
@Autowired
private PlatformTransactionManager transactionManager;
@Bean
public TransactionInterceptor txAdvice(){
DefaultTransactionAttribute tAttr_REQUIRED=new DefaultTransactionAttribute();
tAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
DefaultTransactionAttribute tAttr_REQUIRED_READONLY=new DefaultTransactionAttribute();
tAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
tAttr_REQUIRED_READONLY.setReadOnly(true);
NameMatchTransactionAttributeSource source=new NameMatchTransactionAttributeSource();
source.addTransactionalMethod("add*", tAttr_REQUIRED);
source.addTransactionalMethod("save*", tAttr_REQUIRED);
source.addTransactionalMethod("delete*", tAttr_REQUIRED);
source.addTransactionalMethod("update*", tAttr_REQUIRED);
source.addTransactionalMethod("exec*", tAttr_REQUIRED);
source.addTransactionalMethod("set*", tAttr_REQUIRED);
source.addTransactionalMethod("get*", tAttr_REQUIRED_READONLY);
source.addTransactionalMethod("query*", tAttr_REQUIRED_READONLY);
source.addTransactionalMethod("find*", tAttr_REQUIRED_READONLY);
source.addTransactionalMethod("list*", tAttr_REQUIRED_READONLY);
source.addTransactionalMethod("count*", tAttr_REQUIRED_READONLY);
source.addTransactionalMethod("is*", tAttr_REQUIRED_READONLY);
return new TransactionInterceptor(transactionManager, source);
}
@Bean
public Advisor txAdviceAdvisor(){
AspectJExpressionPointcut pointcut=new AspectJExpressionPointcut();
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, txAdvice());
}
}
try{}catch{}中事务不回滚
回滚只有在RunTimeException 或者 Error时,才会发生回滚。而常见的非RunTimeException是不会触发事务回滚的。
RunTimeException:这样的异常在程序里不做处理,不会报错,运行时才会报错,例如:NullPointerException空指针异常。
非RunTimeException:在程序里要进行try catch处理,不进行处理就会报错
处理事务不回滚的几种方法:
1.抛出@Transactional注解默认识别的RuntimeException
public int saveBatch(){
Logger logger=LogManager.getLogger();
try {
List<UmsRole> ls=new ArrayList<UmsRole>();
ls.add(new UmsRole("zhangsan1"));
ls.add(new UmsRole());
ls.add(new UmsRole("zhangsan"));
for (UmsRole umsRole : ls) {
roleMapper.insertSelective(umsRole);
}
} catch (Exception e) {
logger.error(e);
throw new RuntimeException();
}
return 1;
}
2. 使用@Transactional(rollbackFor = { Exception.class }),抛出捕获的非RuntimeException异常
方法上使用@Transactional(rollbackFor = { Exception.class })注解声明事务回滚级别,在捕获到异常时在catch语句中直接抛出所捕获的异常。
@Transactional(rollbackFor={Exception.class})
public int saveBatch(){
Logger logger=LogManager.getLogger();
try {
List<UmsRole> ls=new ArrayList<UmsRole>();
ls.add(new UmsRole("zhangsan1"));
ls.add(new UmsRole());
ls.add(new UmsRole("zhangsan"));
for (UmsRole umsRole : ls) {
roleMapper.insertSelective(umsRole);
}
} catch (Exception e) {
logger.error(e);
throw e;
}
return 1;
}
3. 手动回滚
上面两个在catch{…}中抛出异常的方法都有个不足之处,就是不能在catch{…}中存在return子句,所以设置手动回滚,当捕获到异常时,手动回滚,同时返回前台提示信息
public int saveBatch(){
Logger logger=LogManager.getLogger();
try {
List<UmsRole> ls=new ArrayList<UmsRole>();
ls.add(new UmsRole("zhangsan1"));
ls.add(new UmsRole());
ls.add(new UmsRole("zhangsan"));
for (UmsRole umsRole : ls) {
roleMapper.insertSelective(umsRole);
}
} catch (Exception e) {
logger.error(e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
return 1;
}