spring事务隔离级别、传播机制以及简单配置方式

一、spring支持的事务声明方式

1. 编程式事务 当系统需要明确的,细粒度的控制各个事务的边界,应选择编程式事务。

2. 声明式事务 当系统对于事务的控制粒度较粗时,应该选择申明式事务,通过<tx>标签和<aop>切面形式在xml中进行配置。

3. 无论你选择上述何种事务方式去实现事务控制,spring都提供基于门面设计模式的事务管理器供选择,如下是spring事务中支持的事务管理器


事务管理器实现(org.springframework.*)


使用时机


jdbc.datasource.DataSourceTransactionManager


使用jdbc的抽象以及ibatis支持


orm.hibernate.HibernateTransactionManager


使用hibernate支持(默认3.0以下版本)


orm.hibernate3.HibernateTransactionManager


使用hibernate3支持


transaction.jta.JtaTransactionManager


使用分布式事务(分布式数据库支持)


orm.jpa.JpaTransactionManager


使用jpa做为持久化工具


orm.toplink.TopLinkTransactionManager


使用TopLink持久化工具


orm.jdo.JdoTransactionManager


使用Jdo持久化工具


jms.connection.JmsTransactionManager


使用JMS 1.1+


jms.connection.JmsTransactionManager102


使用JMS 1.0.2


transaction.jta.OC4JJtaTransactionManager


使用oracle的OC4J JEE容器


transaction.jta.WebLogicJtaTransactionManager


在weblogic中使用分布式数据库


jca.cci.connection.CciLocalTransactionManager


使用jrping对J2EE Connector Architecture (JCA)和Common Client Interface (CCI)的支持

配置示例如下:

<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <propertyname="dataSource" ref="dataSource"/> //引入数据源
</bean>

二、spring支持7种事务传播行为


传播行为


含义


propagation_required(xml文件中为required)


表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚)


propagation_supports(xml文件中为supports)


表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行


propagation_mandatory(xml文件中为mandatory)


表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常


propagation_nested(xml文件中为nested)


表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation_required的一样


propagation_never(xml文件中为never)


表示当方法务不应该在一个事务中运行,如果存在一个事务,则抛出异常


propagation_requires_new(xml文件中为requires_new)


表示当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。


propagation_not_supported(xml文件中为not_supported)


表示该方法不应该在一个事务中运行。如果有一个事务正在运行,他将在运行期被挂起,直到这个事务提交或者回滚才恢复执行

三、spring中的事务隔离级别


隔离级别


含义


isolation_default


使用数据库默认的事务隔离级别


isolation_read_uncommitted


允许读取尚未提交的修改,可能导致脏读、幻读和不可重复读


isolation_read_committed


允许从已经提交的事务读取,可防止脏读、但幻读,不可重复读仍然有可能发生


isolation_repeatable_read


对相同字段的多次读取的结果是一致的,除非数据被当前事务自生修改。可防止脏读和不可重复读,但幻读仍有可能发生


isolation_serializable


完全服从acid隔离原则,确保不发生脏读、不可重复读、和幻读,但执行效率最低。

脏读、不可重复读、幻象读概念说明:

a.脏读:指当一个事务正字访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。依据脏数据所做的操作肯能是不正确的。

b.不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事物内两次连续读到的数据是不一样的,这种情况被称为是不可重复读。

c.幻象读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中)

四、spring事务只读属性

spring事务只读的含义是指,如果后端数据库发现当前事务为只读事务,那么就会进行一系列的优化措施。它是在后端数据库进行实施的,因此,只有对于那些有可能启动一个新事务的传播行为(REQUIRED,REQUIRES_NEW,NESTED)的方法来说,才有意义。(测试表明,当使用JDBC事务管理器并设置当前事务为只读时,并不能发生预期的效果,即能执行删除,更新,插入操作)

五、spring的事务超时

有的时候为了系统中关键部分的性能问题,它的事务执行时间应该尽可能的短。因此可以给这些事务设置超时时间,以秒为单位。我们知道事务的开始往往都会发生数据库的表锁或者被数据库优化为行锁,如果允许时间过长,那么这些数据会一直被锁定,影响系统的并发性。

因为超时时钟是在事务开始的时候启动,因此只有对于那些有可能启动新事物的传播行为(REQUIRED,REQUIRES_NEW,NESTED)的方法来说,事务超时才有意义。

六、事务回滚规则

spring中可以指定当方法执行并抛出异常的时候,哪些异常回滚事务,哪些异常不回滚事务。默认情况下,只在方法抛出运行时异常的时候才回滚(runtime exception)。而在出现受阻异常(checked exception)时不回滚事务。当然可以采用申明的方式指定哪些受阻异常像运行时异常那样指定事务回滚。

七、单个方法的事务传播机制(注意这里说的是单个方法)

1、整备工作: spring申明式事务配置,将aop,tx命名空间添加到当前的spring配置文件头中,这里不在累述

2、定义一个事务AOP通知(add开头名单方法)

<tx:advice id="txAdvice" transactionManager="transactionManager">
 <tx:attributes>
  <tx:methodname="add*" propagation="REQUIRED"/>
 </tx:attributes>
</tx:advice>

3、定义一个事务切面,即应该在哪些类的哪些方法上面进行事务切入,多个包体可以使用||隔开

<aop:config>
 <aop:advisor pointcut="execution(* *..zx.spring.UserService*.*(..))||execution(**..spring.ServiceFacade.*(..))||execution(**..spring.BookService.*(..))"
advice-ref="txAdvice"/>
</aop:config>

4、事务通知中Propagation设置为7中传播行为的情况如下(单方法):

@1、方法的事务传播机制为REQUIRED, REQUIRES_NEW,并且抛出运行时异常时,将回滚事务。当方法抛出受检查的异常时,将不会回滚事务。

@2、方法的事务传播机制为MANDATORY,由于单个方法执行没有指定任何事务传播机制,因此抛出异常。

@3、方法的事务传播机制为NESTED,由于NESTED内嵌事务,如果没有外层事务,则新建一个事务,行为同REQUIRED一样。

@4、方法的事务传播机制为NEVER,由于发生运行时异常,事务本应该回滚,但是事务传播机制为NEVER,因此找不到事务进行回滚。

@5、方法的事务传播机制为NOT_SUPPORTED,单个方法被执行时,不会创建事务。如果当前有事务,将封装事务挂起,知道该方法执行完成再恢复封装事务,继续执行。

@6、方法的事务传播机制为SUPPORTS,单个方法 调用时supports行为同NEVER一样,不会创建事务,只是如果有事务,则会加入到当前事务中去。

八、多个方法间的事务传播机制(注意这里说的是多个方法)

1、整备工作: spring申明式事务配置,将aop,tx命名空间添加到当前的spring配置文件头中,不在累述。

2、定义一个事务AOP通知(add开头名单方法)

<tx:advice id="txAdvice" transactionManager="transactionManager">
 <tx:attributes>
  <tx:methodname="add*" propagation="REQUIRED"/>
<tx:methodname="update*" propagation="REQUIRED"/>
 </tx:attributes>
</tx:advice>

3、定义一个事务切面,即应该在哪些类的哪些方法上面进行事务切入

<aop:config>
 <aop:advisor pointcut="execution(**..zx.spring.UserService*.*(..))||execution(**..spring.ServiceFacade.*(..))||execution(**..spring.BookService.*(..))"
advice-ref="txAdvice"/>
</aop:config>

4、事务通知中Propagation设置为7中传播行为的情况如下(多方法间传递):

@1、多个方法的事务传播机制都为REQUIRED,由于REQUIRED方式是如果有一个事务,则加入事务中,如果没有,则新建一个事务,也就是说方法1一开始就会创建一个事务,而方法2发现有事务存在则会加入到事务中,方法2抛出运行时异常,整个事务将会回滚。如果方法2抛出的是可捕获异常,事务将不起作用,方法1执行成功插入,方法2异常中断。或者我们将方法2设置rollback-for属性,那么在指定的异常之内事务都将回滚

@2、方法1的事务传播机制为REQUIRED,方法2的事务传播机制为NEVER,由于方法1会创建一个事务,而方法2是NEVER,不应该在事务中运行,因此导致了冲突会报错。Existingtransaction found for transaction marked with propagation 'never'

@3、方法1的事务传播机制为REQUIRED,方法2的事务传播机制为MANDATORY,执行机制和@1一致。

@4、方法1的事务传播机制为REQUIRED,方法2的事务传播机制为NESTED,内嵌事务,也就是方法1执行体内放入方法2的调用,由于方法2的事务传播机制为NESTED内嵌事务,因此,开始一个新的事务。并且方法2内部抛出RuntimeException,因此内部嵌套事务回滚到外层事务创建的保存点。

注意这个地方,我们抛出的是运行时异常,如果我们抛出受检查的异常,那么spring会默认的忽略此异常。

如果内层事务抛出检查异常,那么外层事务将忽略此异常,但是会产生一个问题。那就是:外层事务使用jdbc的保存点API来实现嵌套事务,

但是数据库不一定支持。我做测试的是oracle数据库,jdbc事务管理器在内层事务抛出检查异常后,将会在内层事务结束后,释放外层事务创建的保存点,这个时候数据库不一定支持。因此可能会抛出如下异常java.sql.SQLException:不支持的特性。

总结: 对于NESTED内层事务而言,内层事务独立于外层事务,可以独立递交或者回滚,如果内层事务抛出的是运行异常,外层事务进行回滚,内层事务也会进行回滚。

@5、方法1的事务传播机制为REQUIRED,方法2的事务传播机制为REQUIRES_NEW。(情况比较复杂)

情况一,方法2不抛出任何异常下:方法1先创建事务,但是方法2也要运行在自己的事务中,因此也会创建一个事务,方法1的事务将会挂起,直到方法2的事务执行完成才会接着事务的提交完成

情况二,方法2抛出运行时异常下: 对于REQUIRES_NEW事务传播机制,如果被调用端(方法2)抛出运行时异常,则被调用端事务回滚,如果调用段代码(方法1)捕获了被调用端抛出的运行时异常,那么调用端事务提交,不回滚。反之,如果调用段代码未捕获被调用端抛出的运行时异常,那么调用端事务回滚,不提交。

@6、方法1的事务传播机制为REQUIRED,方法2的事务传播机制为SUPPORTS,方法1创建一个事务,方法2加入到当前事务中,方法2抛出运行异常将进行事务的回滚,如果方法1不具有事务,由于方法2的特性是事务环境可有可无,方法2也不会运行在事务中,所以也不会进行回滚。如果方法2抛出的是受检查异常,异常将会忽略,事务将会提交,当然还有别的情况没有一一验证

@7、方法1的事务传播机制为REQUIRED,方法2的事务传播机制为NOT_SUPPORTED,由于方法2事务特性,方法1的事务将会被挂起,方法2抛出运行时异常,但是方法2是不在事务环境中运行的,所以回滚不了,而方法1中未捕获此异常,将进行事务回滚,如果方法2抛出的是运行异常,即使方法1没有捕获此异常,也将被忽略,不进行事务的回滚。

PS:以上都是对粗粒度的方法的事务操作,都是在数据无问题,特意抛出异常的情况下来判断事务的特性,并在什么情况下事务将会起作用。而且spring的事务,在服务类内部的方法间调用,有可能存在被调用方法配置的事务不起作用,调用方在加上事务就起作用了。还值得测试深究

九、spring声明式事务配置的几种方式

1、基于@Transactional注解(推荐配置)

<!-- 事务管理器,对mybatis操作数据库进行事务控制,spring使用jdbc的事务控制类 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceSuport"></property>
</bean>
<!—开启spring 事务注解支持 mode="aspectj"表示采用切面 mode="proxy"表示代理模式(默认) -->
 <tx:annotation-driven transaction-manager="transactionManager" />

MyBatis自动参与到spring事务管理中,无需额外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可,否则事务管理会不起作用。

@Transactional可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。 虽然@Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外,@Transactional 注解应该只被应用到public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用@Transactional 注解,这将被忽略,也不会抛出任何异常。默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。

2、基于<tx>与<aop>切面的方式进行事务配置

<!-- 事务管理器,对mybatis操作数据库进行事务控制,spring使用jdbc的事务控制类 -->
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSourceSuport"></property>
 </bean>

 <!-- spring 事务注解 mode="aspectj"表示采用切面 mode="proxy"表示代理模式(默认) -->
 <tx:annotation-driven transaction-manager="transactionManager" />
 <!-- 通知 映射到上面的事务管理器-->
 <tx:advice id="txAdive"transaction-manager="transactionManager">
 <tx:attributes>
  <!--name什么方法名称开头 传播行为 REQUIRED必须事务 rollback-for什么异常类进行回滚,逗号隔开 -->
  <tx:method name="save*" propagation="REQUIRED"rollback-for="java.lang.DaoException"/>
  <tx:method name="delete*" propagation="REQUIRED"rollback-for="java.lang.DaoException"/>
  <tx:method name="insert*" propagation="REQUIRED"rollback-for="java.lang.DaoException"/>
  <tx:method name="update*" propagation="REQUIRED"rollback-for="java.lang.DaoException"/>
  <!-- 不是必须的,而且查询类型为事务只读的可以提高数据库性能优化 -->
  <tx:method name="find*" propagation="SUPPORTS"read-only="true"/>
  <tx:method name="get*" propagation="SUPPORTS"read-only="true"/>
  <tx:method name="select*" propagation="SUPPORTS"read-only="true"/>
 </tx:attributes>
 </tx:advice>
 <!-- aop切面并配置切入点入进行事物管理 指向上面的映射 -->
 <aop:config>
 <aop:pointcut expression="execution(* com.zht.service.serviceImpl.*.*(..))"id="txPointcut"/>
 <aop:advisor advice-ref="txAdive" pointcut-ref="txPointcut"/>
 </aop:config>
 <aop:aspectj-autoproxy proxy-target-class="true"/>

3、基于TransactionProxyFactoryBean (bean工厂代理)--需要显示的为每一个业务类配置,每多一个业务类就要进行添加,这里不在描述。

4、基于TransactionInterceptor(事务拦截器)的方式进行配置。

<bean id="transactionManager"class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<propertyname="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<!--事务拦截器,激活事务管理器所必须的bean -->
<bean id="transactionInterceptor"class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<!--配置事务属性 -->
<property name="transactionAttributes">
<props>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!--定义事务处理代理bean,他需要两个属性,一个是指定需要代理的bean,另一个是代理bean所需的事务拦截器 -->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>tempService</value>
</list>
</property>
<propertyname="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
<!--业务逻辑层 -->
<bean id="tempService" class="com.cj.transaction.service.TempService"abstract="false"

lazy-init="default"autowire="default" dependency-check="default">
<property name="userDAO">
<ref bean="userDAO" />
</property>
<property name="deptDAO">
<ref bean="deptDAO" />
</property>
</bean>
<bean id="userDAO" class="com.cj.transaction.hibernate.UserDAO">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="deptDAO"class="com.cj.transaction.hibernate.DeptDAO">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

如果模块过多话,可以考虑根据bean的名称用自动创建事务代理的方式

<!--自动代理 -->
<bean id="autoproxy"class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Service</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>

PS:以上为自己收集以及在spring+springMVC+mybatis框架测试总结的一些内容,特记录下,如果有理解错的地方望拍砖指出,感激不尽。希望能给大家一个参考,也希望大家多多支持我们。。

(0)

相关推荐

  • 详解SpringCloud-Alibaba-Seata分布式事务

    前言 Seata 是一款阿里巴巴开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务. Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案. 术语 TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚. TM (Transaction Manager) -

  • Spring事务传播属性和隔离级别详细介绍

    1 事务的传播属性(Propagation) 1) REQUIRED ,这个是默认的属性 Support a current transaction, create a new one if none exists. 如果存在一个事务,则支持当前事务.如果没有事务则开启一个新的事务. 被设置成这个级别时,会为每一个被调用的方法创建一个逻辑事务域.如果前面的方法已经创建了事务,那么后面的方法支持当前的事务,如果当前没有事务会重新建立事务. 2) MANDATORY Support a curren

  • Spring Boot事务配置详解

    1.在启动主类添加注解:@EnableTransactionManagement 来启用注解式事务管理,相当于之前在xml中配置的<tx:annotation-driven />注解驱动. 2.在需要事务的类或者方法上面添加@Transactional() 注解,里面可以配置需要的粒度: 这么多东西提供配置: Isolation :隔离级别 隔离级别是指若干个并发的事务之间的隔离程度,与我们开发时候主要相关的场景包括:脏读取.重复读.幻读. 我们可以看 org.springframework.

  • Spring 事务隔离与事务传播的详解与对比

    Spring 事务隔离与事务传播的详解与对比 Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring的事务管理分为声明式跟编程式.声明式就是在Spring的配置文件中进行相关配置:编程式就是用注解的方式写到代码里. Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSource. Tr

  • Spring实现声明式事务的方法详解

    1.回顾事务 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎! 事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性. 事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. 事务四个属性ACID 原子性(atomicity) 事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用. 一致性(consistency) 一旦所有事务动作完成,事务就要被提交.数据和资源处于一种满足业务规则的一致性状态中.

  • Springcloud seata分布式事务实现代码解析

    Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.本篇不涉及其原理,只用代码构建项目简单试用一下其回滚的机制. 大致上seata分为TC,TM,RM三大构建成整体.它们之间的包含关系如下.即一(xid主键编码,记录信息)带三(TC,TM,RM) 下面之间构建项目进行测试. 1.下载seata并解压,然后改动配置文件. http://seata.io/zh-cn/blog/download.html官网下载. 解压之后到conf中修改file和registry

  • spring事务隔离级别、传播机制以及简单配置方式

    一.spring支持的事务声明方式 1. 编程式事务 当系统需要明确的,细粒度的控制各个事务的边界,应选择编程式事务. 2. 声明式事务 当系统对于事务的控制粒度较粗时,应该选择申明式事务,通过<tx>标签和<aop>切面形式在xml中进行配置. 3. 无论你选择上述何种事务方式去实现事务控制,spring都提供基于门面设计模式的事务管理器供选择,如下是spring事务中支持的事务管理器 事务管理器实现(org.springframework.*) 使用时机 jdbc.dataso

  • Spring事务隔离级别简介及实例解析

    本文研究的主要是Spring事务隔离级别(solation level)介绍及例子,具体如下. 当两个事务对同一个数据库的记录进行操作时,那么,他们之间的影响是怎么样的呢?这就出现了事务隔离级别的概念.数据库的隔离性与并发控制有很大关系.数据库的隔离级别是数据库的事务特性ACID的一部分.ACID,即原子性(atomicity).一致性(consistency).隔离性(isolation)和持久性(durability).Spring的事务隔离级别有四个:READ_UNCOMMITTED.RE

  • Spring框架事务属性中事务隔离级别与传播行为全面讲解

    目录 一.事务隔离级别 ①介绍 ②使用方式 二.事务传播行为 ①介绍 ②测试 一.事务隔离级别 ①介绍 数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题.一个事 务与其他事务隔离的程度称为隔离级别.SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同 的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱. 隔离级别一共有四种: 读未提交:READ UNCOMMITTED 允许Transaction01读取Transaction02未提交的修改. 读已提交

  • Spring中的事务隔离级别和传播行为

    目录 传播行为 举个例子进行说明 1>PROPAGATION_REQUIRED 2>PROPAGATION_SUPPORTS 3>PROPAGATION_MANDATORY 4>PROPAGATION_REQUIRES_NEW 5>PROPAGATION_NOT_SUPPORTED 6>PROPAGATION_NEVER 7>PROPAGATION_NESTED 总结 Spring的事务隔离级别和事务的传播行为是面试中经常考察的问题,做个简单的总结. 传播行为 在

  • 深入理解Mysql事务隔离级别与锁机制问题

    概述 数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能导致脏读.脏写.不可重复度和幻读.这些问题的本质都是数据库的多事务并发问题,为了解决事务并发问题,数据库设计了事务隔离机制.锁机制.MVCC多版本并发控制隔离机制,用一整套机制来解决多事务并发问题. 事务及其ACID属性 原子性:操作的不可分割: 一致性:数据的一致性: 隔离性:事务之间互不干扰: 持久性:数据的修改时永久的: 并发事务处理带来的问题 脏写:丢失更新,最后的更新覆盖了由其他事务所做的更

  • 深入分析MSSQL数据库中事务隔离级别和锁机制

    锁机制 NOLOCK和READPAST的区别. 1.       开启一个事务执行插入数据的操作. BEGIN TRAN t INSERT INTO Customer SELECT 'a','a' 2.       执行一条查询语句. SELECT * FROM Customer WITH (NOLOCK) 结果中显示"a"和"a".当1中事务回滚后,那么a将成为脏数据.(注:1中的事务未提交) .NOLOCK表明没有对数据表添加共享锁以阻止其它事务对数据表数据的修

  • 这一次搞懂Spring事务是如何传播的

    前言 上一篇分析了事务注解的解析过程,本质上是将事务封装为切面加入到AOP的执行链中,因此会调用到MethodInceptor的实现类的invoke方法,而事务切面的Interceptor就是TransactionInterceptor,所以本篇直接从该类开始. 正文 事务切面的调用过程 public Object invoke(MethodInvocation invocation) throws Throwable { // Work out the target class: may be

  • MySQL中Innodb的事务隔离级别和锁的关系的讲解教程

    前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库又是个高并发的应用,同一时间会有大量的并发访问,如果加锁过度,会极大的降低并发处理能力.所以对于加锁的处理,可以说就是数据库对于事务处理的精髓所在.这里通过分析MySQL中InnoDB引擎的加锁机制,来抛砖引玉,让读者更好的理解,在事务处理中数据库到底做了什么. 一次封锁or两段锁? 因为有大量的并发访问,为了预防死锁,一般应用中推荐使用一次封锁法,就是在方法的开始阶段,已经预先知道会

  • 简述MySql四种事务隔离级别

    隔离级别: 隔离性其实比想象的要复杂. 在SQL标准中定义了四种隔离级别, 每一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的.较低级别的隔离通常可以执行更高的并发,系统的开销也更低. 下面简单地介绍一下四种隔离级别. 1.READ UNCOMMITTED(未提交读) 在 READ UNCOMMITTED级别, 事务中的修改, 即使没有提交, 对其他事务也都是可见的. 事务可以读取未提交的数据, 这也被称为脏读 (Dirty Read). 这个级别会导致很多问题,从性能上来说,

随机推荐