概述
本文通过 aop注解,实现对事务的管理
注意: 真实项目中,spring集成mybatis,并不是这样的
本文根据 spring IoC 集成mybatis 中的工程做修改
修改pom.xml
增加依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
全部依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
实现 ServiceProxy 类
@Component
@Aspect
public class ServiceProxy {
@Resource
private SqlSession sqlSession;
@Pointcut("execution(* top.malaoshi.service.*.save*(..))")
public void ptSave(){
}
@Pointcut("execution(* top.malaoshi.service.*.update*(..))")
public void ptUpdate(){
}
@Pointcut("execution(* top.malaoshi.service.*.delete*(..))")
public void ptDelete(){
}
@Pointcut("execution(* top.malaoshi.service.*.query*(..))")
public void ptQuery(){
}
//凡是query、save、update、delete开头的方法,都执行session.close()关闭连接
@After("ptQuery() || ptSave() || ptUpdate() || ptDelete()")
public void close(){
System.out.println("======ServiceProxy.close()");
sqlSession.close();
}
//凡是save、update、delete开头的方法,都执行事务管理
@Around("ptSave() || ptUpdate() || ptDelete()")
public Object tranactional(ProceedingJoinPoint pjp) throws Throwable {
Object res=null;
try{
res=pjp.proceed(pjp.getArgs());
System.out.println("======ServiceProxy.commit()");
sqlSession.commit();
} catch (Throwable throwable) {
sqlSession.rollback();
System.out.println("======ServiceProxy.rollback()");
throw throwable;
}
return res;
}
}
注意:
注意:这里容易犯错
这里不能使用 @AfterReturning 注解处理事务提交、@AfterThrowing 注解处理事务回滚,因为 @After 在这两个注解前执行,即:先关闭session,然后再 提交事务或 回滚事务,会报错
修改 ApplicationConfig 类
增加 @EnableAspectJAutoProxy 注解
测试-save 成功
主启动类如下:
public class Main {
public static void main(String[] args) throws Exception {
ApplicationContext ac=new AnnotationConfigApplicationContext(ApplicationConfig.class);
IUserService srv=(IUserService)ac.getBean("userSrvImpl");
User user=new User();
user.setId(UUID.randomUUID().toString().replace("-",""));
user.setUsername("李现");
user.setPassword("123456");
srv.save(user);
}
}
执行结果:
======ServiceProxy.commit()
======ServiceProxy.close()
提交事务、并关闭session
测试-save报错
修改 UserSrvImpl类的 save() 方法
public int save(User user) throws Exception {
int i= mapper.save(user);
i=1/0;//除以0,故意报错
return i;
}
执行结果:
======ServiceProxy.rollback()
======ServiceProxy.close()
报错后回滚事务
测试-query
修改主启动类
public class Main {
public static void main(String[] args) throws Exception {
ApplicationContext ac=new AnnotationConfigApplicationContext(ApplicationConfig.class);
IUserService srv=(IUserService)ac.getBean("userSrvImpl");
List<User> list=srv.queryByName("李%");
for(User user:list){
System.out.println(user.getUsername());
}
}
}
执行结果:
======ServiceProxy.close()
李雷
李四
李娜
执行关闭session