Spring复习-事务

事务概述

Spring事务编程概述
事务是开发中必不可少的东西,使用JDBC开发时,我们使用connnection对事务进行控制,使用MvBatis时,我们使用SqlSession对事务进行控制,缺点显而易见,当我们切换数据库访问技术时,事务控制的方式总会变化,Spring 就将这些技术基础上,提供了统一的控制事务的接口。Spring的事务分为:编程式事务控制 和 声明式事务控制

Spring事务编程相关的类主要有如下三个

虽然编程式事务控制我们不学习,但是编程式事务控制对应的这些类我们需要了解一下,因为我们在通过配置的方式进行声明式事务控制时也会看到这些类的影子

转账环境

搭建测试环境
搭建一个转账的环境,dao层一个转出钱的方法,一个转入钱的方法,service层一个转账业务方法,内部分别调用dao层转出钱和转入钱的方法,准备工作如下:
1.数据库准备一个账户表tb_account;
2.dao层准备一个AccountMapper,包括incrMoney和decrMoney两个方法
3.service层准备一个transferMoney方法,分别调用incrMoney和decrMoney方法;
4.在applicationContext文件中进行Bean的管理配置;
测试正常转账与异常转账。

xml方式

基于xml声明式事务控制
结合上面我们学习的AOP的技术,很容易就可以想到,可以使用AOP对Service的方法进行事务的增强。
1.目标类:自定义的AccountServicempl,内部的方法是切点
2.通知类:Spring提供的,通知方法已经定义好,只需要配置即可

我们分析:
1.通知类是Spring提供的,需要导入Spring事务的相关的坐标;
2.配置目标类AccountServicelmpl;
3.使用advisor标签配置切面。

具体使用:给转账方法加Spring事务

<!--平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--Spring提供好的通知类-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
    <!--name:通配符,isolation事务隔离级别,propagation事务传播(A调B),只读,超时(秒)-->
    <tx:method name="transferMoney" isolation="READ_COMMITTED" propagation="REQUIRED" read-only="false" timeout="3"/>
<!--            <tx:method name="insert*"/>-->
<!--            <tx:method name="update*"/>-->
    </tx:attributes>
</tx:advice>

<aop:config>
    <!--切点-->
    <aop:pointcut id="txPointcut" expression="execution(* com.demo.service.impl.*.*(..))"/>
    <!--织入-->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"></aop:advisor>
</aop:config>

注解方式

半注解方式

定义transactionManager的bean,手动设置开启tx注解

<!--平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启注解-->
<tx:annotation-driven></tx:annotation-driven>

@Transactional注解使用

@Override
@Transactional(value = "transactionManager",isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED,readOnly = false)
public void transferMoney(String outName, String inName, Integer money) {
    accountMapper.subMoney(outName, money);
    int i = 1/0;
    accountMapper.addMoney(inName, money);
}

全注解方式

写完整的配置类

@Configuration
@ComponentScan(basePackages = {"com.demo"}) //替代<context:component-scan>
@PropertySource(value = "classpath:jdbc.properties") //替代<context:property-placeholder>
@MapperScan("com.demo.mapper")
@EnableTransactionManagement //<tx:annotation-driven></tx:annotation-driven>读取TransactionManagement的bean
public class SpringConfig {
    @Bean
    public DataSource dataSource(@Value("${jdbc.driver}") String driverName,
                                 @Value("${jdbc.url}") String url,
                                 @Value("${jdbc.username}") String username,
                                 @Value("${jdbc.password}") String password) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
    }

    @Bean
    public TransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

切点表达式与事务属性配置的区别

基于xml声明式事务控制
其中,name属性名称指定哪个方法要进行哪些事务的属性配置,此处需要区分的是切点表达式指定的方法与此处指定的方法的区别?切点表达式,是过滤哪些方法可以进行事务增强;事务属性信息的name,是指定哪个方法要进行哪些事务属性的配置。

posted @ 2025-02-25 20:54  Helix_node  阅读(23)  评论(0)    收藏  举报