Spring:事务管理

事务

什么是事务?

事务是数据库操作最基本单元,逻辑上,一组操作要么都成功,如果有一个失败就都失败。

  • 事务的四大特性(ACID):原子性、一致性、隔离性、持久性。
    • 原子性:不可分割的,要么都成功,要么都失败。
    • 一致性:总量不会减少(A给B转了100块钱,A-100,B+100)
    • 隔离性:多事务时,各个事务之间不会产生影响。
    • 持久性:事务提交后,数据永久的保存。

在银行转账业务中,首先是用户A扣除一定金额,然后再给用户B增加一定金额。这就是一个事务,他们不可分割,总量不会减少,其他的事务不会影响这个事务,一旦提交了,数据就永久保存。

  • 事务操作说明
    1. 开启事务
    2. 进行业务
    3. 没有发生异常,事务提交
    4. 如果异常,事务回滚。

​ 一般而言,事务添加在Service层。事务方式分为两种:编程式事务管理和声明式事务管理。一般使用声明式。声明式事务管理有基于注解方式和基于xml配置文件方式进行,一般使用基于注解方式。Spring提供了一个接口PlatformTransactionManager(事务管理器),根据不同的框架提供了不同的接口的实现(JDBC和MyBatis使用DataSourceTransactionManager


基于注解方式实现事务管理

  1. 在Spring中配置事务管理器,并完成数据源注入。

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
  2. 在Spring中开启注解扫描

    1. 先配置名称空间tx

    2. 开启事务注解并指定哪一个事务管理器

      <tx:annotation-driven transaction-manager="TransactionManager"/>
      
  3. 在service类或方法上添加事务注解。@Transactional


@Transactional的参数配置。

  • propagation:事务的传播行为:多事务方法直接进行调用,这个过程中事务是如何进行管理的。
    • Required:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,这是最常见的选择,也是Spring默认的事务传播行为。当内部方法和外部方法都有事务时,内部方法需要回滚时,外部方法不会回滚;如果外部方法没有事务,内部方法有事务,则只回滚内部方法;如果外部方法有事务,内部方法没有事务,则他们属于同一事务,回滚时都会回滚。
    • 其他可以同理可得。
  • isolation:事务的隔离级别
    • 读未提交READ_UNCOMMITTED——出现脏读、不可重复度、幻读。不能容忍的。
    • 读已提交READ_COMMITTED——出现不可重复度、幻读。可以容忍的。
    • 可重复读REPEATABLE_READ——出现幻读。可以容忍的。
    • 串行化SERIALIZABLE——都可以解决,但是并发性差。可能会导致最后一张票被多个人购买。一般不使用。
  • timeout:超时时间
  • readOnly:是否只读
  • rollBackFor:回滚。
  • noRollBackFor:不会滚。

基于XML方式实现事务管理

  1. 配置xml文件

  2. 配置事务管理器参数

    <tx:advice id="tx">
        <tx:attributes>
            <tx:method name="transfer"/>
        </tx:attributes>
    </tx:advice>
    
  3. 配置切入点、切面

    <aop:config>
        <aop:pointcut id="pt" expression="execution(* com.boerk.txDemo.service.*(..))"/>
        <aop:advisor advice-ref="tx" pointcut-ref="pt"></aop:advisor>
    </aop:config>
    

基于完全注解开发实现事务操作

@Configuration
@ComponentScan(basePackages="com.boerk")
@EnableTransactionManagement
public class SpringConfig {
@Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource;
        druidDataSource.setUrl("jdbc:mysql://localhost:3307/boerk");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("root123");
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return druidDataSource;
    }
    @Bean
    public JdbcTemplate getJdbcTemplate(DruidDataSource druidDataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(druidDataSource);
        return jdbcTemplate;
    }
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DruidDataSource druidDataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(druidDataSource);
        return dataSourceTransactionManager;
    }

}
上一篇:haproxy的简介


下一篇:动态数据源玩起来