其他分享
首页 > 其他分享> > 05-Spring-事务管理

05-Spring-事务管理

作者:互联网

 

1.事务管理

  1. 概念:

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

    如果有一个失败操作那么所有的操作都失败

  2. 事务四个特性(ACID)

事务的运行

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

2.声明式事务管理

2.1 实现步骤
  1. 创建配置事务管理器

    DataSourceTransactionManage (针对JdbcTemplate或Mybatis)

  2. 开启事务

    @EnableTransactionManagement 或者配置 < tx:annotation-driven/>

  3. 在需要进行事务处理的类或者方法上添加事务注解

    @Transactional

(1)基于注解实现

配置类:SpringConfig.java

@Configuration
@ComponentScan(basePackages = {"com.potato"})
@EnableTransactionManagement  // 2.开启事务注解
public class SpringConfig {

    //1.创建配置事务管理器 DataSourceTransactionManager 
    @Bean(name = "transactionManager")
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean(name = "dataSource")
    public DataSource createDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/spring5");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }
    @Bean(name = "jdbcTemplate")
    public JdbcTemplate createDataSource(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        return jdbcTemplate;
    }
}

需要事务处理的类:BankServiceImpl.java

//3.在需要进行事务处理的类或者方法上添加事务注解  
@Transactional
@Override
public Integer transferAccounts(String saveAccount, String takeAccount, int money) {
    Integer take = bankDao.take(takeAccount, money);
    Integer save = bankDao.save(saveAccount, money);

    return take == save ? (take != 0 ? 1 : 0) : 0;
}
(2)基于xml配置文件实现

配置文件

<context:component-scan base-package="com.potato"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.driver.jdbc.mysql"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/spring5"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg ref="dataSource"/>
</bean>

<!--    1.创建事务管理器-->
<bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

<!--    2.开启事务注解-->
<tx:annotation-driven transaction-manager="transactionManager"/>
2.2 Spring事务管理API :PlatformTransactionManager接口

在这里插入图片描述

PlatformTransactionManager:事务管理的接口,有多个不同的实现类分别针对不同的数据处理框架

DataSourceTransactionManager :JdbcTemplate、Mybatis

HibernateTransactionManager:Hibernate

2.3 @Transactional 相关参数

在这里插入图片描述

propagation:事务传播行为

isolation:事务隔离级别

timeout:超时时间

readOnly:是否只读

rollbackFor:发生指定的异常则回滚

noRollbackFor:发生指定的异常则不回滚

2.4 传播行为:propagation
传播属性解析
REQUIRED(默认) 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,
就继续使用该事务。这是最常见的选择。
REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。
NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,
则执行与REQUIRED类似的操作。
2.5 隔离级别:isolation
  1. 不考虑隔离性 则会产生以下三个问题

    • 脏读:

      在多事务之间:一个未提交的事务读取到另一个未提交事务的数据

    • 不可重复读

      两个事务,事务A与事务B,事务A在自己执行的过程中,执行了两次相同查询,

      第一次查询事务时B未提交,第二次查询事务时B已提交,从而造成两次查询结果不一样

    • 幻读(虚读)

      在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

  2. 隔离级别参数

    属性值脏读不可重复读幻读
    READ_UNCOMMITTED(读未提交)
    READ_COMMITTED(读以提交)
    REPEATABLE_READ(可重复读) (默认)
    SERIALIZABLE(串行化)
2.6 其他参数

3.编程式事务管理

标签:事务管理,回滚,当前,05,Spring,事务,dataSource,提交
来源: https://www.cnblogs.com/yangyufu/p/16686870.html