学习Spring5必知必会(7)~Spring tx

2022-03-13  本文已影响0人  一乐乐

一、spring的事务管理

1、引出事务的经典例子:银行转账发生异常

✿ 解决:把转出钱和转入钱的业务放到同一个事务空间。

■ 分析转账过程流程:

① 首先,获取 DataSource 对象;
② 其次,获取 DataSource 中的 Connection 对象;
③ 接着,设置取消事务的自动提交方式: connection.setAutoCommit(false);
④ 然后,把 connection 绑定到当前线程中;
从当前线程中获取 Connection 对象
⑥ 如果正常执行,则提交事务:提交事务:connection.commit(); 如果出现异常,则回滚事务:回滚事务:connection.rollback();



2、Spring 的事务管理主要包括 3 个:PlatformTransactionManager、TransactionDefinition、TransactionStatus


■ PlatformTransactionManager

图片.png

✿ 记:常用的事务管理器:


3、事务传播规则 TransactionDefinition

(1)事务的传播规则(传播行为):

在一个事务方法中,调用了其他事务的方法,此时事务该如何传递,按照什么规则传播.

图片.png

(2)传播规则适应的情况:

■ 情况一:需要尊重/遵从当前事务

■ 情况二:不遵从当前事务的

■ 情况三:寄生事务(外部事务/内部事务/嵌套事务)



二、事务配置

1、使用xml配置jdbc事务

    <!-- ===============好比是AOP,事务增强================================== -->
    <!-- 1、what:配置jdbc事务管理器 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- 2:when:配置事务管理器增强(环绕增强) --><!-- 关联what -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="trans"/>
        </tx:attributes>
    </tx:advice>
    
    <!-- 3、where:配置切面 --><!-- 关联when -->
    <aop:config>
        <aop:pointcut id="txPc" expression="execution(* com.shan.service.*Service.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/>
    </aop:config>


2、事务增强的属性配置 <<tx:method/>> 元素的属性:

属性 必要? 默认 描述
name 匹配方法的模式
propagation 事务的传播规则 required
isolation 事务的隔离级别 default DEFAULT:使用数据库自身设置的隔离级别,其他四种都是Spring通过java代码模拟出来的
timeout 事务超时时间 -1 缺省 -1 表示使用底层数据库自身的超时时间
read-only 是否是只读事务 false 若对于查询方法,设置只读,会提高性能,例如Hibernate
rollback-for 遇到什么异常做回滚 java.lang.RuntimeException 当我们在业务方法中,抛出一个Runtime异常,则事务回滚。自定义异常,若是需要配置多个异常,使用,隔开
no-rollback-for 遇到什么异常不做回滚


3、使用注解配置jdbc事务

■ 注解@Transactional使用:

@Service@Transactional
public class AccountServiceImpl implements IAccountService{
    
    @Autowired
    private IAccountDAO dao;

    @Override
    public void trans(Long outId, Long inId, int money) {
        dao.transOut(outId, money);
        int a = 1/0; //算术异常
        dao.transIn(inId, money);   
    }
    
    //若是有查询方法,可以再贴注解@Transactional添加注解属性
    @Transactional(readOnly = true)
    public void listXX() {
        
    }

}



4、Java Config 配置

@Configuration 配置

@import(配置子类)

@Bean 配置创建bean对象

@ComponentScan ioc注解解析器

@EnableTransactionManagement 事务注解解析器

图片.png

■ DataSourceConfig.java

//当前项目的连接池的配置类
@Configuration
@PropertySource("classpath:db.properties")
public class DataSourceConfig {
    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Value("${jdbc.initialSize}")
    private int initialSize;
    
    //配置连接池的Bean
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driverClassName);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        ds.setInitialSize(initialSize);
        return ds;
    }
}

■ AppConfig.java

//当前项目的配置类,好比是pplicationContext.xml
@Configuration //标识当前类为一个配置类
@Import(DataSourceConfig.class) //包含其他的配置类
@ComponentScan //ioc注解解析器【di注解解析器默认是导入的】
@EnableTransactionManagement//事务注解解析器
public class AppConfig {
    
    //创建事务管理的Bean
    @Bean
    public DataSourceTransactionManager txManager(DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }
}

■ App.java

@SpringJUnitConfig(classes = AppConfig.class)
public class App {
    
    @Autowired
    private IAccountService service;
    
    @Test
    void testTrans() throws Exception {
        service.trans(1L, 2L, 100);
    }
}


写在后面的话

       如果你觉得一乐的文章给您带来了一些收获,可以给个三连❤️ ,一乐会一如既往地更新有价值的博客。如果文章存在错误,也欢迎大家指出。还有,如果大家有什么好的学习技巧、学习感悟,也非常欢迎大家在评论区一起交流~

最后感谢大家的支持,谢谢~

上一篇下一篇

猜你喜欢

热点阅读