Spring事务管理知多少?面试时会讲吗?工作时会用吗?来点简单的

185 篇文章 1 订阅
41 篇文章 0 订阅

本文转载自:Spring事务管理知多少?面试时会讲吗?工作时会用吗?来点简单的


Spring事务的其实就是数据库对事务的支持,使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交

事务是指在一系列的数据库操作过程中,一旦其中某一个动作出现错误,可以进行全部回滚,让系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态,避免出现由于数据不一致而导致的接下来一系列的错误。

事务的出现是为了确保数据的完整性和一致性,在实际开发中,事务管理是必不可少的。

一、事务基础

1. 事务有四大特性(ACID)

  • 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
  • 一致性(Consistency):事务在完成时,必须是所有的数据都保持一致状态。
  • 隔离性(Isolation):并发事务执行之间无影响,在一个事务内部的操作对其他事务是不产生影响,这需要事务隔离级别来指定隔离性。
  • 持久性(Durability):一旦事务完成,数据库的改变必须是持久化的。

2. 事务并发问题

在企业级应用中,多用户访问数据库是常见的场景,这就是所谓的事务的并发。事务并发所可能存在的问题:

  • 脏读:一个事务读到另一个事务未提交的更新数据。
  • 不可重复读:一个事务两次读同一行数据,可是这两次读到的数据不一样。
  • 幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
  • 丢失更新:撤消一个事务时,把其它事务已提交的更新的数据覆盖了。

二、Spring事务

Spring事务管理的核心接口是PlatformTransactionManager ;事务管理器接口通过getTransaction方法根据指定的传播行为返回当前活动的事务或创建一个新的事务,这个方法里面的参数是TransactionDefinition类,这个类就定义了一些基本的事务属性。

在TransactionDefinition接口中定义了它自己的传播行为和隔离级别 ,源码如下:

public interface TransactionDefinition {
    int PROPAGATION_REQUIRED = 0;
    int PROPAGATION_SUPPORTS = 1;
    int PROPAGATION_MANDATORY = 2;
    int PROPAGATION_REQUIRES_NEW = 3;
    int PROPAGATION_NOT_SUPPORTED = 4;
    int PROPAGATION_NEVER = 5;
    int PROPAGATION_NESTED = 6;
    int ISOLATION_DEFAULT = -1;
    int ISOLATION_READ_UNCOMMITTED = 1;
    int ISOLATION_READ_COMMITTED = 2;
    int ISOLATION_REPEATABLE_READ = 4;
    int ISOLATION_SERIALIZABLE = 8;
    int TIMEOUT_DEFAULT = -1;

    int getPropagationBehavior();
    int getIsolationLevel();
    int getTimeout();
    boolean isReadOnly();
    @Nullable
    String getName();
}

1. Spring传播途径

以下途径支持当前事务

  1. propagation_required:默认,表示当前必须有事务;当前有事务,则支持当前事务,如果不存在 就新建一个
  2. propagation_supports:表示支持当前事务;如果不存在,就不使用事务
  3. propagation_mandatory:支持当前事务,如果当前事务不存在,抛出异常

以下途径不支持当前事务

  1. propagation_requires_new:表示新建一个事务,也就是说,如果当前没有事务则新建一个,就算有,也挂起当前事务,新建一个的事务,
  2. propagation_not_supported:表示不支持当前事务;如果有事务存在,挂起当前事务 ,没有则以非事务方式运行
  3. propagation_never:表示不要事务,以非事务方式运行;如果有事务存在,就抛出异常
  4. propagation_nested:表示嵌套事务;如果当前存在事务,则在嵌套事务内执行。(换句话说就是,他的提交是要等和他的父事务一块提交的,父回滚他回滚);如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

2. Spring事务的隔离级别

  • ISOLATION_DEFAULT:默认隔离级别,使用数据库默认的事务隔离级别
  • ISOLATION_READ_UNCOMMITTED:未提交读;充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。这是事务最低的隔离级别
  • ISOLATION_READ_COMMITTED:提交读(Oracle\sqlserver 默认),保证一个事务修改的数据提交后才能被另外一个事务读取
  • ISOLATION_REPEATABLE_READ:可重复读(Mysql 默认);这个事务不结束,别的事务就不可以改这条记录,加锁;这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻读。
  • SERIALIZABLE(serializable):串行化(级别最高),花费最高代价。事务被处理为顺序执行,运行完一个事务的所有子事务之后才可以执行另外一个事务,有效的防止脏读,不可重复读 和幻读。

三、配置事务管理器

Spring提供了两种事务管理的方式:编程式事务管理和声明式事务管理

1. 编程式事务管理

编程式事务管理我们可以通过PlatformTransactionManager实现来进行事务管理,同样的Spring也为我们提供了模板类TransactionTemplate进行事务管理,下面主要介绍模板类,我们需要在配置文件中配置

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>
<!--配置事务管理的模板-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="transactionManager"></property>
    <!--定义事务隔离级别,-1表示使用数据库默认级别-->
    <property name="isolationLevelName" value="ISOLATION_DEFAULT"></property>
    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"></property>
</bean>

2. 声明式事务管理

声明式事务管理有两种常用的方式,一种是基于tx和aop命名空间的xml配置文件,一种是基于@Transactional注解,随着Spring和Java的版本越来越高,大家越趋向于使用注解的方式

①. 基于tx和aop命名空间的xml配置文件

<!--基于数据源的数据管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource"/>
<!--  配置事务传播特性 -->
<tx:advice id="advice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="insert" propagation="REQUIRED" read-only="false"  rollback-for="Exception"/>
    </tx:attributes>
</tx:advice>
<!--  配置参与事务的类 -->
<aop:config>
    <aop:pointcut id="pointCut" expression="execution (* com.gray.service.*.*(..))"/>
    <aop:advisor advice-ref="advice" pointcut-ref="pointCut"/>
</aop:config>

②. 基于@Transactional注解

开启对注解事务管理的支持

<!-- 声明式事务管理 配置事物的注解方式注入-->
<tx:annotation-driven transaction-manager="transactionManager"/>

在需要事务管理的地方加上@Transactional注解,如:

@Transactional(rollbackFor=Exception.class)
public void insert(String sql, boolean flag) throws Exception {
    dao.insertSql(sql);
    // 如果flag 为 true ,抛出异常
    if (flag){
        throw new Exception("has exception!!!");
    }
}

本文转载自:Spring事务管理知多少?面试时会讲吗?工作时会用吗?来点简单的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值