spring中使用aop机制为service package下的所有增删改方法添加事务

事务有两种配置方式

1. 使用@Transactional显式的注解式事务

2. 声明式事务,又叫隐式事务,所以不是没有加@Transactional注解就一定没有事务

下面是一个声明式事务的使用场景,其使用了spring Transaction底层的api支持,如PlatformTransactionManager

Spring 的事务机制提供了一个 PlatformTransactionManager 接口,不同的数据访问技术的事务使用不同的接口实现。

使用JPA作为数据库访问技术时,spring boot使用的是 JpaTransactionManager,而使用JDBC作为数据库访问技术时,spring boot使用的是 DataSourceTransactionManage

实际工作中,spring的建议是你在具体的类(或类的方法上)使用@Transactional注解,service下每个类的每个方法都让我们加上@Transactional注解,工作量有点大,也有时候会忘,所以经常看到有开发团队配置拦截式事务

只需要在我们的项目中新增一个子类AspectjTransactionConfig即可

@Configuration
@EnableTransactionManagement
public class AspectjTransactionConfig {

    public static final String transactionExecution = "execution(* com.hfi.service..*.*(..))";

    @Autowired
    private PlatformTransactionManager transactionManager;

    /**
     * 定义通知类
     * @return
     */
    @Bean
    public DefaultPointcutAdvisor defaultPointcutAdvisor() {
        // 指定不同的方法用不同的策略 查询基本上不需要事务支持
        Properties attributes = new Properties();
//        attributes.setProperty("get*", "PROPAGATION_REQUIRED,-Exception");
        attributes.setProperty("add*", "PROPAGATION_REQUIRED,-Exception");
        attributes.setProperty("save*", "PROPAGATION_REQUIRED,-Exception");
        attributes.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
//        attributes.setProperty("select*", "PROPAGATION_REQUIRED,-Exception");

        // 创建interceptor
        TransactionInterceptor interceptor = new TransactionInterceptor(transactionManager, attributes);

        // 定义切入点:指定一般要拦截哪些类
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(transactionExecution);

        // 配置通知类advisor
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setPointcut(pointcut);
        advisor.setAdvice(interceptor);
        return advisor;
    }
}

这样我们的service就自动拥有了事务,可以加@Transactional类覆盖全局的配置

测试:

    public Employee saveTwoEmployee(Employee employee) {

        // 模拟两次执行

        addEmp(employee);



//        int template = 5/0;



        employee.setLastName("cl");

        Employee employee1 = addEmp(employee);

        return employee1;

    }

当我们启用了DefaultPointcutAdvisor,事务在执行完第一个addEmp之后,报错后,会回滚。而没有启用DefaultPointcutAdvisor,事务不会回滚。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值