龙空技术网

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

Java架构师丨苏先生 1395

前言:

眼前同学们对“mysqlspring事务”大概比较重视,兄弟们都想要剖析一些“mysqlspring事务”的相关文章。那么小编也在网络上搜集了一些对于“mysqlspring事务””的相关文章,希望姐妹们能喜欢,各位老铁们快快来学习一下吧!

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传播途径

以下途径支持当前事务

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

以下途径不支持当前事务

propagation_requires_new:表示新建一个事务,也就是说,如果当前没有事务则新建一个,就算有,也挂起当前事务,新建一个的事务,propagation_not_supported:表示不支持当前事务;如果有事务存在,挂起当前事务 ,没有则以非事务方式运行propagation_never:表示不要事务,以非事务方式运行;如果有事务存在,就抛出异常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!!!");    }}
Java程序员福利:我把2019近一年经历过的Java岗位面试,和一些刷过的面试题都做成了PDF,PDF都是可以免费分享给大家的,关注私信我:【101】,免费领取!

标签: #mysqlspring事务