springAop实现事务管理控制

Aop简要概述:

       Aop面向切面编程,可以实现代码的解耦合,提高代码的复用性。

      1:切面:

                   切面的意思通俗的意思就是切入的代码,比如开启事务方法的代码,提交事务的代码

      2:切入点:

                   需要切入代码的地方,比如待执行代码的前,或者后

      3:连接点

                   满足规则的地方,定位到某个类,或者方法

      4:通知

                   通知分为:前置通知,后置通知,环绕通知,异常通知

spring实现事务控制代码:

一:引入依赖(为了方便起见,使用springboot2版本,懒得再去一个一个引入依赖信息)

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
</dependencies>

二:配置application.yml文件

server:
  port: 8080 #服务器端口号
spring:
  jpa:
    database: mysql #使用 jpa 
    show-sql: true 
  datasource:
    driver-class-name: com.mysql.jdbc.Driver  数据库驱动
    username: root 用户名
    password: 1234  密码
    url: jdbc:mysql://localhost:3306/clouddb01?useUnicode=true&amp;characterEncoding=UTF8 数据库地址

三:创建启动类

package com.zbin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 启动类
 *
 * @author zhangbin 2019年03月22日
 * @version 1.0
 * @since 1.0 2019年03月22日
 */
@SpringBootApplication
public class AopApplication {
    public static void main(String[] args) {
        SpringApplication.run(AopApplication.class,args);
    }
}

至此,该项目可以正常启动了

四:创建工具类,用于开启事务,提交事务,会滚事务

package com.zbin.aop;

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;
//注入spring容器中
@Component
//创建为多例对象,放置多线程安全问题
@Scope("prototype")
public class AopAspectUtil {
    @Autowired
    private DataSourceTransactionManager manager; //注入spring的事务管理器
   //事务拦截器
    private TransactionStatus transaction;

    /**
     * @return org.springframework.transaction.TransactionStatus
     * @Author zhangbin
     * @Description 开启事务
     * @Date 9:54 2019/3/25
     * @Param []
     **/
    public TransactionStatus begin() {
        transaction = manager.getTransaction(new DefaultTransactionAttribute());//设置为默认事务隔离级别
       //返回事务拦截器
        return transaction;
    }

    /**
     * @return void
     * @Author zhangbin
     * @Description 提交事务
     * @Date 9:54 2019/3/25
     * @Param []
     **/
    public void commit() {
       // 提交事务
        manager.commit(transaction);
    }

    /**
     * @return void
     * @Author zhangbin
     * @Description 会滚事务
     * @Date 9:54 2019/3/25
     * @Param []
     **/
    public void rollback() {
       //回滚事务
        manager.rollback(transaction);
    }
}

五:定义注解

package com.zbin.aop.mytransation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE,ElementType.METHOD})//设置注解使用范围
@Retention(RetentionPolicy.RUNTIME)//注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
public @interface MyTransactional {
}

六:自定义通知

使用注意,在针对事务管理方面,方法中不要去try{}catch(){},使用try,,catch后aop不能获取到异常信息,会导致出现异常后不能进行回滚,如果确实需要try,,,catch 可以再finally中加上TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();由此段代码进行事务的回滚

package com.zbin.aop.transaction;

import com.zbin.aop.mytransation.TransactionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
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.interceptor.TransactionAspectSupport;

@Component
@Aspect
public class AopTransaction {
    @Autowired
    private TransactionUtils transactionUtils;

    @Around("execution(* com.zbin.aop.service.UserService.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //调用方法之前执行
        System.out.println("开启事务");
       transactionUtils.begin();
        proceedingJoinPoint.proceed();
        //调用方法之后执行
        System.out.println("提交事务");
        transactionUtils.commit();

    }

    @AfterThrowing("execution(* com.zbin.aop.service.UserService.add(..))")
    public void afterThrowing() {
        System.out.println("异常通知  ");
        //获取当前事务进行回滚
        //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        transactionUtils.rollBack();
    }
}

七:测试效果 ,,自行测试

@MyTransactional
public void add() {
    userDao.add("test001", 20);
    int i = 1 / 0;
    System.out.println("---------------------");
    userDao.add("test002", 20);
}

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值