Spring事务-事务开启的两种方式

2019-08-09  本文已影响0人  探索者_逗你玩儿

在Spring框架中事务的开启有两种方式,一种是申明式开启,一种是编程开启。申明式开启即通过xml配置文件配置TransactionManager的形式启动事务,通过配置AOP切点进行方法的拦截来实现

<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置事务管理器类 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 配置事务增强(如果管理事务?) -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="*" read-only="false"/>
        </tx:attributes>
    </tx:advice>
    
    <!-- Aop配置: 拦截哪些方法(切入点表表达式) + 应用上面的事务增强配置 -->
    <aop:config>
        <aop:pointcut expression="execution(* cn.unicorn.service.DeptService.save(..))" id="pt"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
    </aop:config>

另一种是通过编程开启事务,这种方式对业务的代码的侵入性太强,但是控制粒度更细,如果对事务控制精度有要求可以采取这种模式。下面来看看具体的列子

/**
     * 数据源加入事务管理
     * @param masterDataSource
     * @return
     */
    @Bean(name = "transactionManager")
    @Primary
    public DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("masterDataSource") DataSource masterDataSource){
        final DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(masterDataSource);
        return dataSourceTransactionManager;
    }

 /**
     * 事务管理加入事务模板
     * @param transactionManager
     * @return
     */
    @Bean(name = "transactionTemplate")
    @Primary
    public TransactionTemplate masteerTransactionTemplate(@Qualifier("transactionManager") DataSourceTransactionManager transactionManager){
        final TransactionTemplate transactionTemplate = new TransactionTemplate();
        transactionTemplate.setTransactionManager(transactionManager);
        transactionTemplate.setIsolationLevelName("ISOLATION_DEFAULT");
        transactionTemplate.setPropagationBehaviorName("PROPAGATION_REQUIRED");
        return transactionTemplate;
    }
@Override
    public void addUsers(List<User> users){
        TransactionCallback transactionCallback = new TransactionCallback() {
            @Nullable
            @Override
            public Object doInTransaction(TransactionStatus status) {
                try {
                    for (User user : users) {
                        int i = userMapper.insert(user);
                        if (i == 1) {
                            System.out.println("添加成功");
                        } else {
                            System.out.println("添加失败");
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("出现异常,回滚");
                    //设置事务回滚
                    status.setRollbackOnly();
                }
                return null;
            }
        };
        transactionTemplate.execute(transactionCallback);
    }

从两个例子中可以看到申明式事务和编程式事务的区别,前者通过配置AOP切点,对业务代码零侵入,后者对业务代码的侵入比较厉害,但是控制精度更高,这两种模式在开发中可以根据自己的需要选择对应的方式,也可两者混用。

上一篇 下一篇

猜你喜欢

热点阅读