精华内容
下载资源
问答
  • 数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为 Read uncommitted:允许脏读。 Read committed: 防止脏读,最常用的隔离级别,并且是大多数数据库的默认隔离级别。 Repeatable read:可以防止脏...
  • 事务隔离级别:一个事务对数据库的修改与并行的另一个事务的隔离程度
  • 数据库事务隔离级别

    2011-12-19 14:09:53
    介绍数据库事务的四种隔离级别,比较不同隔离级别的区别和影响
  • 为什么会出现数据库隔离级别呢? 数据库隔离级别是为了解决数据库并发访问过程中产生的各种数据安全问题. 事务的基本要素(ACID) 原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能...
  • 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 代码如下: #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. [mysqld] transaction-...
  • 数据库隔离级别有四种,应用《高性能mysql》一书中的说明:然后说说修改事务隔离级别的方法:1.全局修改,修改mysql.ini配置文件,在最后加上#可选参数有:READ-UNCOMMITTED,READ-COMMITTED,REPEATABLE-READ,...
  • 数据库事务: 针对数据库的某一组操作要么全部成功,要么全部失败。 事务的作用 1:保证数据的完整性,失败后可以恢复到原来状态 2:事务与事务之间互不干扰,这样数据会更加安全 数据库事务ACID属性 / 特性 原子性...
  • 一直没搞清楚spring事务与数据库事务与锁之间的关系。 spring事务: spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁; ...

    一直没搞清楚spring事务与数据库事务与锁之间的关系。

    spring事务:

    spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁;

    那么事务的隔离级别与锁有什么关系呢?本人认为事务的隔离级别是通过锁的机制实现的,事务的隔离级别是数据库开发商根据业务逻辑的实际需要定义的一组锁的使用策略。当我们将数据库的隔离级别定义为某一级别后如仍不能满足要求,我们可以自定义 sql 的锁来覆盖事务隔离级别默认的锁机制。

    spring事务实际使用AOP拦截注解方法,然后使用动态代理处理事务方法,捕获处理过程中的异常,spring事务其实是把异常交给spring处理;

    spring事务只有捕获到异常才会终止或回滚,如果你在程序中try/catch后自己处理异常而没有throw,那么事务将不会终止或回滚,失去事务本来的作用;

    spring事务会捕获所有的异常,但只会回滚数据库相关的操作,并且只有在声明了rollbackForClassName="Exception"之类的配置才会回滚;

    spring事务会回滚同一事务中的所有数据库操作,本质上是回滚同一数据库连接上的数据库操作;

     

    spring事务总结:

    spring事务本质上使用数据库锁;

    spring事务只有在方法执行过程中出现异常才会回滚,并且只回滚数据库相关的操作;

     

    对象锁和spring事务的对比:

    对象锁可以保证数据一致性和业务逻辑正确性,但不能保证并发性;

    spring事务不能严格保证数据一致性和业务逻辑正确性,但具有较好的并发性,因为只锁数据库行数据;

     

    建议:

    如果只有insert操作,可以使用事务;

    如果涉及update操作但不涉及其他业务逻辑,可以保守使用事务;

    如果涉及update操作及其他业务逻辑,慎用事务,

    并且数据库查询跟数据库更新之间尽量间隔较短,中间不宜插入太多其他逻辑,减少数据一致性的风险;

    对数据一致性要求不高的情况下可以使用事务结合乐观锁,否则建议用锁;

     

    spring事务为什么不能保证数据一致性和业务逻辑正确性:

    1.如果事务方法抛异常,此时会回滚数据库操作,但已经执行的其他方法不会回滚,因此无法保证业务逻辑正确性;

    2.即使事务方法不抛异常,也不能保证数据一致性(因为事务接口里的数据库操作在整个接口逻辑执行结束后才提交到数据 库,在接口最后提交到数据库的前后很有可能带来数据一致性的问题),从而不能保证业务逻辑正确性;

     

    Spring 事务的传播属性

    所谓spring事务的传播属性,就是定义在存在多个事务同时存在的时候,spring应该如何处理这些事务的行为。这些属性在TransactionDefinition中定义,具体常量的解释见下表:

    常量名称常量解释
    PROPAGATION_REQUIRED支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,也是 Spring 默认的事务的传播。
    PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。新建的事务将和被挂起的事务没有任何关系,是两个独立的事务,外层事务失败回滚之后,不能回滚内层事务执行的结果,内层事务失败抛出异常,外层事务捕获,也可以不处理回滚操作
    PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
    PROPAGATION_MANDATORY支持当前事务,如果当前没有事务,就抛出异常。
    PROPAGATION_NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常。
    PROPAGATION_NESTED

    如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

    数据库隔离级别

     

    隔离级别隔离级别的值导致的问题
    Read-Uncommitted0导致脏读
    Read-Committed1避免脏读,允许不可重复读和幻读
    Repeatable-Read2避免脏读,不可重复读,允许幻读
    Serializable3串行化读,事务只能一个一个执行,避免了脏读、不可重复读、幻读。执行效率慢,使用时慎重

    Spring中的隔离级别

     

    常量解释
    ISOLATION_DEFAULT这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与 JDBC 的隔离级别相对应。
    ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
    ISOLATION_READ_COMMITTED保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
    ISOLATION_REPEATABLE_READ这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
    ISOLATION_SERIALIZABLE这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

    事务管理:

    <!-- 配置事务管理 -->
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	<property name="dataSource" ref="dataSource" />
    </bean>

    Spring-mybatis 事务声明方式

    xml配置声明方式:

    <!-- 声明式事务管理 -->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
    <!-- 声明式事务管理 -->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
    	<tx:attributes>
    		<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>
    		<tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception" />
    		<tx:method name="testTransaction*" propagation="REQUIRED" rollback-for="Exception" read-only="true"/>
    	</tx:attributes>
    </tx:advice>

    事务切入切面:

    <!-- 配置切面 -->
    <aop:config>
    	<aop:pointcut id="transactionPointcut" expression="execution(* com.youx.qd.app.*.dservice.*.*(..))" />
    	<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
    </aop:config>

    测试事务方法:

    @Override
    //@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.SERIALIZABLE,rollbackFor = Exception.class)
    public ResponseDto testTransactionA() {
        System.out.println("开始事务A");
        iTb****Service.update****(1559540272306292637L,2);
        try {
            Thread.sleep(10000L);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("结束事务A");
    
        return null;
    }

    测试结果:表示在事务控制中该操作只允许读取操作

    Spring的事务管理器

    Spring并不直接管理事务,而是提供了多种事务管理器,它们将事务管理的职责委托给JTA或其他持久化机制所提供的平台相关的事务实现。每个事务管理器都会充当某一特定平台的事务实现的门面,这使得用户在Spring中使用事务时,几乎不用关注实际的事务实现是什么。

    Spring提供了许多内置事务管理器实现:

    • DataSourceTransactionManager位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理;
    • JdoTransactionManager位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理,用于集成JDO框架时的事务管理;
    • JpaTransactionManager位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持,用于集成JPA实现框架时的事务管理;
    • HibernateTransactionManager位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本;
    • JtaTransactionManager位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器;
    • OC4JjtaTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;
    • WebSphereUowTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;
    • WebLogicJtaTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。

    声明事务配置分享

    spring中PROPAGATION类的事务属性详解

    1. PROPAGATION_REQUIRED:         支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 

    2. PROPAGATION_SUPPORTS:         支持当前事务,如果当前没有事务,就以非事务方式执行。 

    3. PROPAGATION_MANDATORY:      支持当前事务,如果当前没有事务,就抛出异常。 

    4. PROPAGATION_REQUIRES_NEW:   新建事务,如果当前存在事务,把当前事务挂起。

    5.  PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 

    6. PROPAGATION_NEVER:               以非事务方式执行,如果当前存在事务,则抛出异常。 

    7. PROPAGATION_NESTED:              支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

     

    如何在Spring配置文件中定义事务管理器:

    声明对本地事务的支持:

    a)JDBC及iBATIS、MyBatis框架事务管理器

    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    通过dataSource属性指定需要事务管理的单个javax.sql.DataSource对象。在幕后DataSourceTransactionManager通过调用java.sql.Connection来管理事务,而后者是通过DataSource获取到的。通过调用连接的commit()方法来提交事务。同样,事务失败时通过调用rollback()方法进行回滚。

    参考文档:https://www.jianshu.com/p/6b275553b54f

    b)Jdo事务管理器

    <bean id="txManager" class="org.springframework.orm.jdo.JdoTransactionManager">
        <property name="persistenceManagerFactory" ref="persistenceManagerFactory"/>
    </bean>

    通过persistenceManagerFactory属性指定需要事务管理的javax.jdo.PersistenceManagerFactory对象。

    c)Jpa事务管理器

    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    通过entityManagerFactory属性指定需要事务管理的javax.persistence.EntityManagerFactory对象。

    还需要为entityManagerFactory对象指定jpaDialect属性,该属性所对应的对象指定了如何获取连接对象、开启事务、关闭事务等事务管理相关的行为。

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            ……
            <property name="jpaDialect" ref="jpaDialect"/>
    </bean>
    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

    d)Hibernate事务管理器

    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    在幕后HibernateTransactionManager将事务管理的职责委托给org.hibernate.Transaction对象,而后者是从Hibernate Session中获取到的。当事务成功完成时,HibernateTransactionManager将会调用Transaction对象的commit()方法来提交事务。同样,事务失败时通过调用Transaction的rollback()方法进行回滚。

    Spring对全局事务的支持:

    a)Jta事务管理器

    <beans xmlns="http://www.springframework.org/schema/beans"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jee="http://www.springframework.org/schema/jee"
        xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/jee
           http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
     
      <jee:jndi-lookup id="dataSource" jndi-name="jdbc/test"/>
      <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManagerName" value=" java:comp/TransactionManager"/>
      </bean>
    </beans>
    “dataSource”Bean表示从JNDI中获取的数据源,而txManager是JTA事务管理器,其中属性transactionManagerName指定了JTA事务管理器的JNDI名字,从而将事务管理委托给该事务管理器。
    

    <tx:method/> 有关的设置 

    展开全文
  • show variables like "transaction_isolation%"; https://blog.csdn.net/qq_38198581/article/details/82017254

    show variables like "transaction_isolation%";

     

    展开全文
  • Mysql四种隔离级别 测试Mysql隔离级别 隔离级别原理分析 一、什么是事务 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务...

    文章目录:

    • 什么是事务
    • 事务的ACID
    • Mysql四种隔离级别
    • 测试Mysql隔离级别
    • 隔离级别原理分析

    一、什么是事务

    事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

    事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作。

    二、事务的 ACID

    事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。

    • 原子性。事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做

    • 一致性。事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。

    • 隔离性。一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

    • 持续性。也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。

    三、Mysql的四种隔离级别

    SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

    Read Uncommitted(读取未提交内容)

    在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

    Read Committed(读取提交内容)

    这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

    Repeatable Read(可重读)

    这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

    Serializable(可串行化)

    这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

    这四种隔离级别采取不同的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。例如:

    • 脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

    • 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

    • 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就有几列数据是未查询出来的,如果此时插入和另外一个事务插入的数据,就会报错。

    在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:

    640?wx_fmt=other

    四、测试Mysql的隔离级别

    下面,将利用MySQL的客户端程序,我们分别来测试一下这几种隔离级别。

    测试数据库为demo,表为test;表结构:

    640?wx_fmt=other

    两个命令行客户端分别为A,B;不断改变A的隔离级别,在B端修改数据。

    将A的隔离级别设置为read uncommitted(未提交读)

    640?wx_fmt=other

    A:启动事务,此时数据为初始状态

    640?wx_fmt=other

    B:启动事务,更新数据,但不提交

    640?wx_fmt=other

    A:再次读取数据,发现数据已经被修改了,这就是所谓的“脏读”

    640?wx_fmt=other

    B:回滚事务

    640?wx_fmt=other

    A:再次读数据,发现数据变回初始状态

    640?wx_fmt=other

    经过上面的实验可以得出结论,事务B更新了一条记录,但是没有提交,此时事务A可以查询出未提交记录。造成脏读现象。未提交读是最低的隔离级别。

    将客户端A的事务隔离级别设置为read committed(已提交读)

    640?wx_fmt=other

    A:启动事务,此时数据为初始状态

    640?wx_fmt=other

    B:启动事务,更新数据,但不提交

    640?wx_fmt=other

    A:再次读数据,发现数据未被修改

    640?wx_fmt=other

    B:提交事务

    640?wx_fmt=other

    A:再次读取数据,发现数据已发生变化,说明B提交的修改被事务中的A读到了,这就是所谓的“不可重复读”

    640?wx_fmt=other

    经过上面的实验可以得出结论,已提交读隔离级别解决了脏读的问题,但是出现了不可重复读的问题,即事务A在两次查询的数据不一致,因为在两次查询之间事务B更新了一条数据。已提交读只允许读取已提交的记录,但不要求可重复读。

    将A的隔离级别设置为repeatable read(可重复读)

    640?wx_fmt=other

    A:启动事务,此时数据为初始状态

    640?wx_fmt=other

    B:启动事务,更新数据,但不提交

    640?wx_fmt=other

    A:再次读取数据,发现数据未被修改

    640?wx_fmt=other

    B:提交事务

    640?wx_fmt=other

    A:再次读取数据,发现数据依然未发生变化,这说明这次可以重复读了

    640?wx_fmt=other

    B:插入一条新的数据,并提交

    640?wx_fmt=other

    A:再次读取数据,发现数据依然未发生变化,虽然可以重复读了,但是却发现读的不是最新数据,这就是所谓的“幻读”

    640?wx_fmt=other

    A:提交本次事务,再次读取数据,发现读取正常了

    640?wx_fmt=other

    由以上的实验可以得出结论,可重复读隔离级别只允许读取已提交记录,而且在一个事务两次读取一个记录期间,其他事务部的更新该记录。但该事务不要求与其他事务可串行化。例如,当一个事务可以找到由一个已提交事务更新的记录,但是可能产生幻读问题(注意是可能,因为数据库对隔离级别的实现有所差别)。像以上的实验,就没有出现数据幻读的问题。

    将A的隔离级别设置为Serializable(可串行化)

    640?wx_fmt=other

    A:启动事务,此时数据为初始状态

    640?wx_fmt=other

    B:发现B此时进入了等待状态,原因是因为A的事务尚未提交,只能等待(此时,B可能会发生等待超时)

    640?wx_fmt=other

    A:提交事务

    640?wx_fmt=other

    B:发现插入成功

    640?wx_fmt=other

    serializable完全锁定字段,若一个事务来查询同一份数据就必须等待,直到前一个事务完成并解除锁定为止。是完整的隔离级别,会锁定对应的数据表格,因而会有效率的问题。

    五、隔离级别原理分析

    一、想要深入理解Mysql的事务隔离级别首先要理解Mysql的共享锁和排他锁。

    1、共享锁

    共享锁也叫读锁(Shared Lock),简称S锁,原理:一个事务获取了一个数据行的共享锁,其他事务能获得该行对应的共享锁,但不能获得排他锁,即一个事务在读取一个数据行的时候,其他事务也可以读,但不能对该数据行进行增删改。

    2、排他锁

    排他锁也叫写锁(Exclusive Lock),简称x锁,原理:一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁(排他锁或者共享锁),即一个事务在读取一个数据行的时候,其他事务不能对该数据行进行增删改查。

    二、事务隔离级别的实现原理

    1、读未提交(READ_UNCOMMITED)

    (1)读取:事务对当前被读取的数据不加锁

    (2)更新:事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级共享锁,直到事务结束才释放。

    2、读已提交(READ_COMMITED)

    (1)读取:事务在读取某数据的瞬间(就是开始读取的瞬间),必须先对其加行级共享锁,一旦读完该行立即释放该行级共享锁。

    (2)更新:事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁,直到事务结束才释放。

    3、可重复读(REPEATABLE_READ)

    (1)读取:事务在读取某数据的瞬间(就是开始读取的瞬间),必须先对其加行级共享锁,直到事务结束才释放。

    (2)更新:事务在更新某数据的瞬间(就是发生更新的瞬间),必须先对其加行级排他锁,直到事务结束才释放。

    4、可串行化(SERIALIZABLE)

    (1)读取:事务在读取数据时,必须先对其加表级共享锁 ,直到事务结束才释放。

    (2)更新:事务在更新数据时,必须先对其加表级排他锁,直到事务结束才释放。

     

    参考资料:

    https://blog.csdn.net/forezp/article/details/88361277

    https://www.jianshu.com/p/443581ddfa3c

    展开全文
  • PG数据库事务隔离级别

    千次阅读 2017-01-28 14:33:19
    Postgres数据库事务隔离级别介绍

    Postgres数据库事务隔离级别介绍


    0. What is Database Transaction?

    数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。 —— [百度百科]

    • A –Atomicity
      事务必须是原子工作单元;要么全都执行成功,要么全都执行不成功。通常,与某个事务关联的操作具有共同的目标,并且是相互依赖的。如果系统只执行这些操作的一个子集,则可能会破坏事务的总体目标。原子性消除了系统处理操作子集的可能性。
    • C –Consistency
      一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态
      拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
    • I –Isolation
      隔离性是当并发访问数据库时,数据库每一个事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离
      即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
    • D –Durability
      事务完成之后,它对于系统的影响是永久性的,该修改即使出现致命的系统故障也将一直保持

    1. Why Isolation is important for DataBase?

    如果不考虑事务隔离性,可能导致以下几种严重的问题

    (1) 脏读

    脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

    当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下。

    update account set money = money + 100 where name = 'B';  (此时A通知B)
    update account set money = money - 100 where name = 'A';

    当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。

    (2) 不可重复读

    不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

    例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

    不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

    在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……

    (3) 幻读

    幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

    幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

    为了解决并发导致的不一致问题(脏读/不可重复读/幻读),SQL标准提出了四种事务隔离级别

    隔离级别脏读不可重复读幻读
    读未提交可能可能可能
    读已提交不可能可能可能
    可重复读不可能不可能可能
    可序列化不可能不可能不可能

    2. How Postgres handle with isolation?

    在PostgreSQL中,你可以请求四种标准事务隔离级别中的任意一种。 但是在内部,实际上只有三种不同的隔离级别,分别对应级别读已提交、可重复读和可串行化。但你你选择了读未提交级别,实际上你得到的是读已提交,并且在PostgreSQL的可重复读实现中幻读是不可能出现的,所以实际的隔离级别可能比你选择的更严格。这是 SQL 标准允许的: 四种隔离级别只定义了哪种现像不能发生,但是没有定义哪种现像一定发生。PostgreSQL只提供三种隔离级别的原因是, 这是把标准的隔离级别映射到多版本并发控制架构的唯一合理方法。 可用的隔离级别的行为在下面小节中详细描述。

    要设置一个事务的事务隔离级别,使用SET TRANSACTION命令。

    重要: 某些PostgreSQL数据类型和函数关于事务的行为有特殊的规则。特别是,对一个序列的修改(以及用serial声明的一列的计数器)是立刻对所有其他事务可见的,并且在作出该修改的事务中断时也不会被回滚。

    (1) 读已提交隔离级别

    读已提交是PostgreSQL中的默认隔离级别。 当一个事务运行使用这个隔离级别时, 一个查询(没有FOR UPDATE/SHARE子句)只能看到查询开始之前已经被提交的数据, 而无法看到未提交的数据或在查询执行期间其它事务提交的数据。实际上,SELECT查询看到的是一个在查询开始运行的瞬间该数据库的一个快照。不过SELECT可以看见在它自身事务中之前执行的更新的效果,即使它们还没有被提交。还要注意的是,即使在同一个事务里两个相邻的SELECT命令可能看到不同的数据, 因为其它事务可能会在第一个SELECT开始和第二个SELECT开始之间提交。

    读已提交模式提供的部分事务隔离对于许多应用而言是足够的,并且这个模式速度快并且使用简单。 不过,它不是对于所有情况都够用。做复杂查询和更新的应用可能需要比读已提交模式提供的更严格一致的数据库视图。

    (2) 可重复读隔离级别

    可重复读隔离级别只看到在事务开始之前被提交的数据;它从来看不到未提交的数据或者并行事务在本事务执行期间提交的修改(不过,查询能够看见在它的事务中之前执行的更新,即使它们还没有被提交)。这是比SQL标准对此隔离级别所要求的更强的保证,并且阻止脏读/不可重复读/幻读 所有现象。如上面所提到的,这是标准特别允许的,标准只描述了每种隔离级别必须提供的最小保护。

    这个级别与读已提交不同之处在于,一个可重复读事务中的查询可以看见在事务开始时的一个快照,而不是事务中当前查询开始时的快照。因此,在一个单一事务中的后续SELECT命令看到的是相同的数据,即它们看不到其他事务在本事务启动后提交的修改。

    可重复读模式提供了一种严格的保证,在其中每一个事务看到数据库的一个完全稳定的视图。不过,这个视图并不需要总是和同一级别上并发事务的某些序列化(一次一个)执行保持一致。例如,即使这个级别上的一个只读事务可能看到一个控制记录被更新,这显示一个批处理已经被完成但是不能看见作为该批处理的逻辑组成部分的一个细节记录,因为它读取空值记录的一个较早的版本。如果不小心地使用显式锁来阻塞冲突事务,尝试用运行在这个隔离级别的事务来强制业务规则不太可能正确地工作。

    (3) 可序列化隔离级别

    可序列化隔离级别提供了最严格的事务隔离。这个级别为所有已提交事务模拟序列事务执行;就好像事务被按照序列一个接着另一个被执行,而不是并行地被执行。但是,和可重复读级别相似,使用这个级别的应用必须准备好因为序列化失败而重试事务。事实上,这个给力级别完全像可重复读一样地工作,除了它会监视一些条件,这些条件可能导致一个可序列化事务的并发集合的执行产生的行为与这些事务所有可能的序列化(一次一个)执行不一致。这种监控不会引入超出可重复读之外的阻塞,但是监控会产生一些负荷,并且对那些可能导致序列化异常的条件的检测将触发一次序列化失败。


    展开全文
  • 只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初 状态。 Isolation(隔离性): 事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正 确性和完整性。同时,并行事务的修改必须与其他并行...
  • MySQL 四种事务隔离级别详解及对比 按照SQL:1992 事务隔离级别,InnoDB默认是可重复读的(REPEATABLE READ)。MySQL/InnoDB 提供SQL标准所描述的所有四个事务隔离级别。你可以在命令行用–transaction-isolation选项...
  •   开篇声明,由于两位大佬排版不够美观,然后又发现一些歧义,因此我集百家之所长,精心整理并排版良好,可放心阅读。 ... 一、数据库事务正确执行的四个基本要素 1.1ACID...
  • 数据库隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏写、脏读、不可重复读、幻读这几类问题。 √: 可能出现...
  • 数据库事务隔离级别.docx数据库事务隔离级别.docx数据库事务隔离级别.docx
  • mysql数据库事务隔离级别[参照].pdf
  • 第一步、关闭操作数据库软件和数据库服务 关闭数据库软件就不说了,下面说关闭数据库服务。 以win10为例 “我的电脑”右键——>...找到“服务和应用程序”..."="号后面就是你需要更改的事务隔离级别:#可选参数有:RE
  • 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. 2 [mysqld] 3 transactio
  • 一、数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类...
  • 项目中,以 Spring 事务为准,因为他重写了数据库隔离级别,但没有直接修改数据库隔离级别
  • 数据库事务隔离级别总结

    万次阅读 多人点赞 2019-06-07 12:23:03
    学习数据库的时候常常会接触到事务, ACID等概念,那么到底什么是数据库的事务,数据库事务又具有哪些特点,和ACID有怎样的关系,事务的隔离级别又是做什么的呢?。 事务及其四大特性? 事务(Transaction):访问并...
  • 数据库事务隔离级别与实现原理

    千次阅读 2019-03-11 10:52:29
    事物的四大特性,即常说的ACID: 1、原子性(Atomic):指的... 3、隔离性(Isolation):指的是多个事物并发执行的时候、一个事物的执行不应当影响到其它的事物、即事物与事物之间是隔离的。 4、持久性(Durabil...
  • 「每日一问」数据库事务隔离级别有哪些?

    万次阅读 多人点赞 2020-07-27 14:59:41
    可串行化 在可串行化(Serializable)级别中,强制事务串行执行,是最高的隔离级别。在这个级别中会在读取的每一行上加锁,可能导致大量的超时和锁竞争问题,所以在实际应用中很少被用到。除非,非常需要确保数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 135,588
精华内容 54,235
关键字:

数据库事物隔离级别

友情链接: gps.zip