`
willwen
  • 浏览: 25685 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

事务隔离级别学习

 
阅读更多

       事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列。事务ACID属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

       原子性:保证事务中的所有操作全部执行或全部不执行。例如执行转账事务,要么转账成功,要么失败。成功,则金额从转出帐户转入到目的帐户,并且两个帐户金额将发生相应的变化;失败,则两个账户的金额都不变。不会出现转出帐户扣了钱,而目的帐户没有收到钱的情况。

       一致性:保证数据库始终保持数据的一致性——事务操作之前是一致的,事务操作之后也是一致的,不管事务成功与否。如上面的例子,转账之前和之后数据库都保持数据上的一致性。

       隔离性:多个事务并发执行的话,结果应该与多个事务串行执行效果是一样的。显然最简单的隔离就是将所有事务都串行执行:先来先执行,一个事务执行完了才允许执行下一个。但这样数据库的效率低下,如:两个不同的事务只是读取同一批数据,这样完全可以并发进行。为了控制并发执行的效果就有了不同的隔离级别。针对多个事务并发情况

       持久性:持久性表示事物操作完成之后,对数据库的影响是持久的,即使数据库因故障而受到破坏,数据库也应该能够恢复。通常的实现方式是采用日志。

 

       事务隔离级别(transaction isolation levels):隔离级别就是对对事务并发控制的等级。ANSIISO SQL将其分为串行化(SERIALIZABLE)、可重复读(REPEATABLE READ)、读已提交(READ COMMITED)、读未提交(READ UNCOMMITED)四个等级。

       为了实现隔离级别通常数据库采用锁(Lock)。一般在编程的时候只需要设置隔离等级,至于具体采用什么锁则由数据库来设置。首先介绍四种等级,然后举例解释后面三个等级(可重复读、读已提交、读未提交)中会出现的并发问题。

       串行化(SERIALIZABLE):所有事务都一个接一个地串行执行,这样可以避免幻读(phantom reads)。对于基于锁来实现并发控制的数据库来说,串行化要求在执行范围查询(如选取年龄在10到30之间的用户)的时候,需要获取范围锁(range lock)。如果不是基于锁实现并发控制的数据库,则检查到有违反串行操作的事务时,需要滚回该事务。

       可重复读(REPEATABLE READ):所有被Select获取的数据都不能被修改,这样就可以避免一个事务前后读取数据不一致的情况。但是却没有办法控制幻读,因为这个时候其他事务不能更改所选的数据,但是可以增加数据,即前一个事务有读锁但是没有范围锁,为什么叫做可重复读等级呢?那是因为该等级解决了下面的不可重复读问题。

       读已提交(READ COMMITED):被读取的数据可以被其他事务修改。这样就可能导致不可重复读。也就是说,事务读取数据时获取读锁,但是读完之后立即释放(不需要等到事务结束),而写锁则是事务提交之后才释放。释放读锁之后,就可能被其他事物修改数据。该等级是Oracle默认的隔离等级。

       读未提交(READ UNCOMMITED):这是最低的隔离等级,允许其他事务看到没有提交的数据。这种等级会导致脏读(Dirty Read)。

       通过一些现象,可以反映出隔离级别的效果。这些现象有:

       更新丢失(lost update):当系统允许两个事务同时更新同一数据是,发生更新丢失。

       脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读。

       非重复读(nonrepeatable read):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。

       幻像(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。

       下面是隔离级别及其对应的可能出现或不可能出现的现象

 

 

Dirty Read 

NonRepeatable Read 

Phantom Read 

Read uncommitted

Possible

Possible

Possible

Read committed

Not possible

Possible

Possible

Repeatable read

Not possible

Not possible

Possible

Serializable

Not possible

Not possible

Not possible

 

ORACLE的隔离级别

ORACLE提供了SQL92标准中的read committed和serializable,同时提供了非SQL92标准的read-only。

read committed:这是ORACLE缺省的事务隔离级别。

        事务中的每一条语句都遵从语句级的读一致性。

        保证不会脏读;但可能出现非重复读和幻像。

serializable:简单地说,serializable就是使事务看起来象是一个接着一个地顺序地执行。

        仅仅能看见在本事务开始前由其它事务提交的更改和在本事务中所做的更改。

        保证不会出现非重复读和幻像。

    Serializable隔离级别提供了read-only事务所提供的读一致性(事务级的读一致性),同时又允许DML操作。

       如果有在serializable事务开始时未提交的事务在serializable事务结束之前修改了serializable事务将要修改的行并进行了提交,则serializable事务不会读到这些变更,因此发生无法序列化访问的错误。(换一种解释方法:只要在serializable事务开始到结束之间有其他事务对serializable事务要修改的东西进行了修改并提交了修改,则发生无法序列化访问的错误。)

       If a serializable transaction contains data manipulation language (DML) that attempts to update any resource that may have been updated in a transaction uncommitted at the start of the serializable transaction, (并且修改在后来被提交而没有回滚),then the DML statement fails. 返回的错误是ORA-08177: Cannot serialize access for this transaction。

        ORACLE在数据块中记录最近对数据行执行修改操作的N个事务的信息,目的是确定是否有在本事务开始时未提交的事务修改了本事务将要修改的行。具体见英文:Oracle permits a serializable transaction to modify a data row only if it can determine that prior changes to the row were made by transactions that had committed when the serializable transaction began. To make this determination efficiently, Oracle uses control information stored in the data block that indicates which rows in the block contain committed and uncommitted changes. In a sense, the block contains a recent history of transactions that affected each row in the block. The amount of history that is retained is controlled by the INITRANS parameter of CREATE TABLE and ALTER TABLE. Under some circumstances, Oracle may have insufficient history information to determine whether a row has been updated by a "too recent" transaction. This can occur when many transactions concurrently modify the same data block, or do so in a very short period. You can avoid this situation by setting higher values of INITRANS for tables that will experience many transactions updating the same blocks. Doing so will enable Oracle to allocate sufficient storage in each block to record the history of recent transactions that accessed the block.

l          The INITRANS Parameter:Oracle stores control information in each data block to manage access by concurrent transactions. Therefore, if you set the transaction isolation level to serializable, you must use the ALTER TABLE command to set INITRANS to at least 3. This parameter will cause Oracle to allocate sufficient storage in each block to record the history of recent transactions that accessed the block. Higher values should be used for tables that will undergo many transactions updating the same blocks.

       read-only:

       遵从事务级的读一致性,仅仅能看见在本事务开始前由其它事务提交的更改。

       不允许在本事务中进行DML操作。

       read only是serializable的子集。它们都避免了非重复读和幻像。区别是在read only中是只读;而在serializable中可以进行DML操作。

l         Export with CONSISTENT = Y sets the transaction to read-only.

l          read committed和serializable的区别和联系:

l         事务1先于事务2开始,并保持未提交状态。事务2想要修改正被事务1修改的行。事务2等待。如果事务1回滚,则事务2(不论是read committed还是serializable方式)进行它想要做的修改。如果事务1提交,则当事务2是read committed方式时,进行它想要做的修改;当事务2是serializable方式时,失败并报错“Cannot serialize access”,因为事务2看不见事务1提交的修改,且事务2想在事务一修改的基础上再做修改。具体见英文:Both read committed and serializable transactions use row-level locking, and both will wait if they try to change a row updated by an uncommitted concurrent transaction. The second transaction that tries to update a given row waits for the other transaction to commit or roll back and release its lock. If that other transaction rolls back, the waiting transaction (regardless of its isolation mode) can proceed to change the previously locked row, as if the other transaction had not existed. However, if the other (blocking) transaction commits and releases its locks, a read committed transaction proceeds with its intended update. A serializable transaction, however, fails with the error "Cannot serialize access", because the other transaction has committed a change that was made since the serializable transaction began.

l         read committed和serializable可以在ORACLE并行服务器中使用。

l          关于SET TRANSACTION READ WRITE:read write和read committed 应该是一样的。在读方面,它们都避免了脏读,但都无法实现重复读。虽然没有文档说明read write在写方面与read committed一致,但显然它在写的时候会加排他锁以避免更新丢失。在加锁的过程中,如果遇到待锁定资源无法锁定,应该是等待而不是放弃。这与read committed一致。

l         语句级的读一致性

l          ORACLE保证语句级的读一致性,即一个语句所处理的数据集是在单一时间点上的数据集,这个时间点是这个语句开始的时间。

l          一个语句看不见在它开始执行后提交的修改。

l          对于DML语句,它看不见由自己所做的修改,即DML语句看见的是它本身开始执行以前存在的数据。

l         事务级的读一致性

l          事务级的读一致性保证了可重复读,并保证不会出现幻像。

l         设置隔离级别

l          设置一个事务的隔离级别

l         SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

l         SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

l         SET TRANSACTION READ ONLY;

l         设置增个会话的隔离级别

l         ALTER SESSION SET ISOLATION_LEVEL SERIALIZABLE;

l         ALTER SESSION SET ISOLATION_LEVEL READ COMMITTED;

 

分享到:
评论

相关推荐

    MySQL事务隔离级别

    MySQL事务隔离级别是数据库管理系统中一个非常重要的概念,它关系到数据的一致性和并发性能。在MySQL中,事务被用于确保数据库操作的原子性、一致性、隔离性和持久性(ACID特性)。事务隔离级别主要涉及四个方面:读...

    事务隔离级别 .docx

    学习事务隔离级别的重要性在于理解其对数据库并发性能和数据一致性的影响。掌握不同隔离级别的特性可以帮助开发者选择最适合应用需求的级别,同时避免可能的数据不一致问题。在企业编程中,遵循最佳实践和标准,如...

    spring 事务传播与隔离级别DEMO

    本DEMO主要探讨的是Spring事务的传播行为和隔离级别,这些概念对于理解和优化数据库操作至关重要。让我们深入理解这些概念及其实际应用。 首先,我们来谈谈事务的传播行为。在Spring中,当一个方法被另一个具有事务...

    事务四大隔离级别的不同

    在数据库管理领域,事务是确保数据一致性的重要机制。在MySQL这样的关系型数据库管理系统中...通过学习和实践MySQL的四大事务隔离级别,我们可以更好地理解其工作原理,并在设计和优化数据库应用程序时做出明智的选择。

    Spring中的事务隔离级别的介绍

    Spring中的事务隔离级别的介绍 在Spring事务管理中,事务隔离级别是一个非常重要的概念,它定义了事务在...以上就是关于Spring中的事务隔离级别的介绍,我们希望本文的内容对大家的学习或者工作具有一定的参考价值。

    oracle 数据库隔离级别学习

    Oracle 数据库隔离级别是数据库事务处理中的核心概念,它决定了事务在并发环境下如何访问和处理数据,以确保...开发和数据库管理员需要根据业务场景和性能需求来选择合适的事务隔离级别,以确保系统的稳定性和可靠性。

    【IT十八掌徐培成】Java基础第24天-03.事务并发现象-隔离级别2-表级锁-隔离级别API.zip

    Java中,JDBC提供了四种事务隔离级别: 1. 读未提交(Read Uncommitted):允许读取尚未提交的数据,可能导致脏读。 2. 读已提交(Read Committed):每次读取的都是事务提交后的最新数据,防止了脏读,但可能有不...

    MySQL事务的基础学习以及心得分享

    MySQL中,可以通过`SELECT @@tx_isolation`查看当前的事务隔离级别,用`SET SESSION TRANSACTION ISOLATION LEVEL`命令来设置隔离级别。在实际应用中,通常根据系统的并发需求和性能要求选择适当的隔离级别,以平衡...

    简述MySql四种事务隔离级别

    主要介绍了MySql四种隔离级别,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下

    spring框架的学习--事务

    - **基于XML的声明式事务管理**:在Spring的配置文件中,使用`<tx:advice>`、`<aop:config>`和`<bean>`标签定义事务规则,如事务的传播行为、隔离级别、超时设置等。 - **基于注解的声明式事务管理**:通过在...

    数据一致性之盾:深入解析SQL事务隔离级别

    SQL(Structured Query Language,结构化查询语言)是一种用于管理和操作关系数据库的标准编程语言。它被广泛用于创建、修改、查询和删除数据库...- **易于学习和使用**:SQL语法直观,易于理解和编写。 - **跨平台**:

    动力节点MySQL数据库入门视频教程-108-事务隔离级别

    动力节点的杜老师讲述的mysql教程,详细讲解了MySQL的相关知识,包括MySQL概述,MySQL应用环境,MySQL系统特性,MySQL初学基础,MySQL管理工具,如何安装MySQL及MySQL新特性,通过观看可掌握MySQL全套知识。

    易语言学习进阶事务处理

    6. **事务隔离级别**:在易语言中,你可能需要了解不同的事务隔离级别,如读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE),并根据实际需求选择...

    mysql事务学习资料(PPT+源码)

    5. **事务隔离级别**:MySQL支持四种隔离级别——读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ,MySQL的默认级别)和串行化(SERIALIZABLE)。不同的隔离级别会带来不同的...

    Spring的声明式事务.doc

    本教程旨在帮助您深入了解 Spring 的事务管理功能,并掌握事务管理的基本概念,如事务隔离级别和事务传播行为。通过学习本教程,您将能够灵活运用 Spring 的事务管理功能,提高企业应用的可靠性和安全性。

    SQL Server事务的控制与并发处理视频

    在实际应用中,应根据系统的并发需求和性能要求选择合适的事务隔离级别。例如,银行转账等需要高度一致性的操作通常会选择串行化级别,而对性能敏感的读操作可能选择较低的隔离级别。 通过学习这个视频教程,你可以...

    全面分析Spring的编程式事务管理与声明式事务管理.doc

    本文总结了 Spring 事务管理的基本概念和机制,包括事务隔离级别、事务传播行为、编程式事务管理和声明式事务管理等。通过对 Spring 事务管理的理解,您将能够灵活运用事务管理机制来确保企业应用的可靠性和数据的...

    事务处理java案例代码

    Java中可以通过设置事务隔离级别来控制这一特性,如读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)、可重复读(REPEATABLE READ)和串行化(SERIALIZABLE)。 4. 持久性(Durability):一旦事务提交,...

Global site tag (gtag.js) - Google Analytics