`

数据库事务隔离级别与锁

 
阅读更多

数据库事务隔离级别与锁

一、事务的4个基本特征 
    当事务处理系统创建事务时,将确保事务有某些特性。组件的开发者们假设事务的特性应该是一些不需要他们亲自管理的特性。这些特性称为ACID特性。 ACID就是:原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily)。 
1、原子性 (Atomicity ) 
    原子性属性用于标识事务是否完全地完成,一个事务的任何更新要在系统上完全完成,如果由于某种原因出错,事务不能完成它的全部任务,系统将返回到事务开始前的状态。 
让我们再看一下银行转帐的例子。如果在转帐的过程中出现错误,整个事务将会回滚。只有当事务中的所有部分都成功执行了,才将事务写入磁盘并使变化 永久化。为了提供回滚或者撤消未提交的变化的能力,许多数据源采用日志机制。例如,SQL Server使用一个预写事务日志,在将数据应用于(或提交到)实际数据页面前,先写在事务日志上。但是,其他一些数据源不是关系型数据库管理系统 (RDBMS),它们管理未提交事务的方式完全不同。只要事务回滚时,数据源可以撤消所有未提交的改变,那么这种技术应该可用于管理事务。 
2、一致性( Consistency ) 
    事务在系统完整性中实施一致性,这通过保证系统的任何事务最后都处于有效状态来实现。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。因为事务开 
始时系统处于一致状态,所以现在系统仍然处于一致状态。 再让我们回头看一下银行转帐的例子,在帐户转换和资金转移前,帐户处于有效状态。如果事务成功地完成,并且提交事务,则帐户处于新的有效的状态。如果事务出错,终止后,帐户返回到原先的有效状态。 
记住,事务不负责实施数据完整性,而仅仅负责在事务提交或终止以后确保数据返回到一致状态。理解数据完整性规则并写代码实现完整性的重任通常落在 开发者肩上,他们根据业务要求进行设计。 当许多用户同时使用和修改同样的数据时,事务必须保持其数据的完整性和一致性。因此我们进一步研究A C I D特性中的下一个特性:隔离性。 
3、隔离性 ( Isolation) 
    在隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在 系统中认为只有该事务在使用系统。 这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。重要的是,在隔离状态执行事务, 系统的状态有可能是不一致的,在结束事务前,应确保系统处于一致状态。但是在每个单独的事务中,系统的状态可能会发生变化。如果事务不是在隔离状态运行, 它就可能从系统中访问数据,而系统可能处于不一致状态。通过提供事务隔离,可以阻止这类事件的发生。在银行的示例中,这意味着在这个系统内,其他过程和事 务在我们的事务完成前看不到我们的事务引起的任何变化,这对于终止的情况非常重要。如果有另一个过程根据帐户余额进行相应处理,而它在我们的事务完成前就 能看到它造成的变化,那么这个过程的决策可能 
建立在错误的数据之上,因为我们的事务可能终止。这就是说明了为什么事务产生的变化,直到事务完成,才对系统的其他部分可见。隔离性不仅仅保 证多个事务不能同时修改相同数据,而且能够保证事务操作产生的变化直到变化被提交或终止时才能对另一个事务可见,并发的事务彼此之间毫无影响。这就意味着 所有要求修改或读取的数据已经被锁定在事务中,直到事务完成才能释放。大多数数据库,例如SQL Server以及其他的RDBMS,通过使用锁定来实现隔离,事务中涉及的各个数据项或数据集使用锁定来防止并发访问。 
4、持久性 (Durabilily) 
    持久性意味着一旦事务执行成功,在系统中产生的所有变化将是永久的。应该存在一些检查点防止在系统失败时丢失信息。甚至硬件本身失败,系统的状态仍能通过在日志中记录事务完成的任务进行重建。持久性的概念允许开发者认为不管系统以后发生了什么变化,完 
成的事务是系统永久的部分。 在银行的例子中,资金的转移是永久的,一直保持在系统中。这听起来似乎简单,但这,依赖于将数据写入磁盘,特别需要指出的是,在事务完全完成并提交后才写 入磁盘的。 所有这些事务特性,不管其内部如何关联,仅仅是保证从事务开始到事务完成,不管事务成功与否,都能正确地管理事务涉及的数据 ,当事务处理系统创建事务 时,将确保事务有某些特性。组件的开发者们假设事务的特性应该是一些不需要他们亲自管理的特性。 
二、为什么需要对事务并发控制 
    如果不对事务进行并发控制,我们看看数据库并发操作是会有那些异常情形 
1、丢失更新(Lost update) 
    两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。 
2、脏读(Dirty Reads) 
    一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险的,因为很可能所有的操作都被回滚。 
3、非重复读(Non-repeatable Reads) 
   一个事务对同一行数据重复读取两次,但是却得到了不同的结果。同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。 
4、二类丢失更新(Second lost updates problem) 
    无法重复读取的特例。有两个并发事务同时读取同一行数据,然后其中一个对它进行修改提交,而另一个也进行了修改提交。这就会造成第一次写操作失效。
5、幻像读(Phantom Reads) 
    事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查 
询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。 
三、数据库的隔离级别 
   为了兼顾并发效率和异常控制,在标准SQL规范中,定义了4个事务隔离级别,(ORACLE和SQLSERER对标准隔离级别有不同的实现 ) 
1、未提交读(Read Uncommitted) 
    直译就是"读未提交",意思就是即使一个更新语句没有提交,但是别 
的事务可以读到这个改变.这是很不安全的。允许任务读取数据库中未提交的数据更改,也称为脏读。 
2、提交读(Read Committed) 
   直译就是"读提交",可防止脏读,意思就是语句提交以后即执行了COMMIT以后 
别的事务就能读到这个改变. 只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 
3、可重复读(Repeatable Read): 
   直译就是"可以重复读",这是说在同一个事务里面先后执行同一个查询语句的时候,得到的结果是一样的.在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读 
4、串行读(Serializable) 
   直译就是"序列化",意思是说这个事务执行的时候不允许别的事务并发执行. 完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

 

四,隔离级别对并发的控制 
下表是各隔离级别对各种异常的控制能力。


LU丢失更新 DR脏读 NRR非重复读 SLU二类丢失更新 PR幻像读
未提交读 RU Y Y Y Y Y
提交读 RC N N Y Y Y
可重复读 RR N N N N Y
串行读 S N N N N N

 

 

顺便举一小例。

MS_SQL: 
--事务一 
set transaction isolation level serializable 
begin tran 
insert into test values('xxx') 
--事务二 
set transaction isolation level read committed 
begin tran 
select * from test 
--事务三 
set transaction isolation level read uncommitted 
begin tran 
select * from test 
在查询分析器中执行事务一后,分别执行事务二,和三。结果是事务二会等待,而事务三则会执行。

ORACLE: 
--事务一 
set transaction isolation level serializable; 
insert into test values('xxx'); 
select * from test; 
--事务二 
set transaction isolation level read committed--ORACLE默认级别 
select * from test 
执行事务一后,执行事务二。结果是事务二只读出原有的数据,无视事务一的插入操作。

MYSQL 
查看InnoDB系统级别的事务隔离级别: 
以下为引用的内容: 
mysql> SELECT @@global.tx_isolation; 
+-----------------------+ 
| @@global.tx_isolation | 
+-----------------------+ 
| REPEATABLE-READ   | 
+-----------------------+ 
1 row in set (0.00 sec) 
查看InnoDB会话级别的事务隔离级别: 
以下为引用的内容: 
mysql> SELECT @@tx_isolation; 
+-----------------+ 
| @@tx_isolation | 
+-----------------+ 
| REPEATABLE-READ | 
+-----------------+ 
1 row in set (0.00 sec) 
修改事务隔离级别: 
以下为引用的内容: 
  mysql> set global transaction isolation level read committed; 
  Query OK, 0 rows affected (0.00 sec) 
  mysql> set session transaction isolation level read committed; 
  Query OK, 0 rows affected (0.00 sec) 
InnoDB的可重复读隔离级别和其他数据库的可重复读是有区别的,不会造成幻象读(phantom read),所谓幻象读,就是同一个事务内,多次select,可以读取到其他session insert并已经commit的数据。下面是一个小的测试,证明InnoDB的可重复读隔离级别不会造成幻象读。测试涉及两个session,分别为 session 1和session 2,隔离级别都是repeateable read,关闭autocommit 
以下为引用的内容: 
mysql> select @@tx_isolation; 
+-----------------+ 
| @@tx_isolation | 
+-----------------+ 
| REPEATABLE-READ | 
+-----------------+ 
1 row in set (0.00 sec) 
  mysql> set autocommit=off; 
  Query OK, 0 rows affected (0.00 sec) 
  session 1 创建表并插入测试数据 
  mysql> create table test(i int) engine=innodb; 
  Query OK, 0 rows affected (0.00 sec)

  mysql> insert into test values(1); 
  Query OK, 1 row affected (0.00 sec) 
  session 2 查询,没有数据,正常,session1没有提交,不允许脏读 
  mysql> select * from test; 
  Empty set (0.00 sec) 
  session 1 提交事务 
  mysql> commit; 
  Query OK, 0 rows affected (0.00 sec) 
  session 2 查询,还是没有数据,没有产生幻象读 
  mysql> select * from test; 
  Empty set (0.00 sec) 
以上试验版本: 
mysql> select version(); 
+-------------------------+ 
| version()       | 
+-------------------------+ 
| 5.0.37-community-nt-log | 
+-------------------------+ 
1 row in set (0.00 sec)

五、并发一致性问题的解决办法 
1 封锁(Locking) 
    封锁是实现并发控制的一个非常重要的技术。所谓封锁就是事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该 数据对象有了一定的控制,在事务T释放它的锁之前,其它的事务不能更新此数据对象。 基本的封锁类型有两种:排它锁(Exclusive locks 简记为X锁)和共享锁(Share locks 简记为S锁)。 
    排它锁又称为写锁。若事务T对数据对象A加上X锁,则只允许T读取和修改A,其它任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其它事务在T释放A上的锁之前不能再读取和修改A。 
    共享锁又称为读锁。若事务T对数据对象A加上S锁,则其它事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了其它事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。 
2 封锁协议 
    在 运用X锁和S锁这两种基本封锁,对数据对象加锁时,还需要约定一些规则,例如应何时申请X锁或S锁、持锁时间、何时释放等。我们称这些规则为封锁协议 (Locking Protocol)。对封锁方式规定不同的规则,就形成了各种不同的封锁协议。下面介绍三级封锁协议。三级封锁协议分别在不同程度上解决了丢失的修改、不 可重复读和读"脏"数据等不一致性问题,为并发操作的正确调度提供一定的保证。下面只给出三级封锁协议的定义,不再做过多探讨。 
    1 级封锁协议是:事务T在修改数据R之前必须先对其加X锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK)。 1级封锁协议可防止丢失修改,并保证事务T是可恢复的。在1级封锁协议中,如果仅仅是读数据不对其进行修改,是不需要加锁的,所以它不能保证可重复读和不 读"脏"数据。 
    2级封锁协议是:1级封锁协议加上事务T在读取数据R之前必须先对其加S锁,读完后即可释放S锁。2级封锁协议除防止了丢失修改,还可进一步防止读"脏"数据。 
    3级封锁协议是:1级封锁协议加上事务T在读取数据R之前必须先对其加S锁,直到事务结束才释放。3级封锁协议除防止了丢失修改和不读'脏'数据外,还进一步防止了不可重复读。 
六、一般处理并发问题时的步骤: 
1、开启事务。 
2、申请写权限,也就是给对象(表或记录)加锁。 
3、假如失败,则结束事务,过一会重试。 
4、假如成功,也就是给对象加锁成功,防止其他用户再用同样的方式打开。 
5、进行编辑操作。 
6、写入所进行的编辑结果。 
7、假如写入成功,则提交事务,完成操作。 
8、假如写入失败,则回滚事务,取消提交。 
9、(7.8)两步操作已释放了锁定的对象,恢复到操作前的状态。

分享到:
评论

相关推荐

    数据库_事务隔离级别与锁.docx

    ### 数据库事务隔离级别与锁 #### 一、事务的基本特征 事务是数据库管理系统的核心概念之一,用于确保数据的一致性和正确性。事务通常具备以下四个特性,即ACID特性: 1. **原子性(Atomicity)**:事务被视为一...

    数据库事务隔离级别

    介绍数据库事务的四种隔离级别,比较不同隔离级别的区别和影响

    06-VIP-深入理解Mysql事务隔离级别与锁机制.pdf

    Mysql事务隔离级别与锁机制是数据库系统中非常重要的概念,它们都是为了解决多事务并发问题而设计的。下面我们将深入讲解这些机制,让大家彻底理解数据库内部的执行原理。 事务及其ACID属性 事务是一个逻辑处理单元...

    MySQL数据库:事务隔离级别.pptx

    事务隔离级别 课程目标 了解 —— 事务隔离级别的概念; 理解 —— 事务隔离的四种级别; 掌握 —— 事务隔离级别的设置; 事务隔离级别 事务隔离:每一个事务都有一个所谓的隔离级,它定义了用户彼此之间隔离和交互...

    数据库事务和隔离级别

    数据库事务和隔离级别

    MSSQL与Oracle数据库事务隔离级别与锁机制对比

    数据库事务隔离级别和锁机制是确保数据库并发操作正确性和一致性的关键组成部分。在数据库系统中,尤其是大型企业级应用,多个用户可能同时访问和修改相同的数据,因此并发控制显得尤为重要。 事务的四个基本特征...

    MY SQL 事务隔离 查询:默认事务隔离级别

    查询:默认事务隔离级别 mysql> select @@tx_isolation;当前会话的默认事务隔离级别 mysql> select @@session.tx_isolation;当前会话的默认事务隔离级别 mysql> select @@global.tx_isolation;全局的事务隔离级别

    数据库事务隔离级别.docx

    ### 数据库事务隔离级别详解 #### 一、引言 在多用户共享的数据库系统中,为了保证数据的一致性和准确性,必须对并发事务进行控制。数据库事务隔离级别是用来管理多个事务之间相互影响的程度,主要解决的问题包括脏...

    数据库事务隔离级别的深入解析与代码实现

    数据库事务隔离级别是确保数据一致性和完整性的重要机制。通过合理设置事务隔离级别,可以在保证数据一致性的同时,优化数据库的并发性能。开发者需要根据具体的应用场景和业务需求,选择最合适的事务隔离级别,并在...

    四种隔离级别与锁

    数据库事务的四种隔离级别的特点描述,他们的使用热度,以及各种锁在隔离级别下的释放时机。

    mysql数据库事务隔离级别借鉴.pdf

    以下是对MySQL数据库事务隔离级别的详细解释。 1. **丢失更新**:在并发环境下,一个事务的更新可能被另一个事务的更新覆盖,导致前一个事务的更改丢失。 2. **脏读**:一个事务读取到了另一个事务还未提交的数据...

    深入理解Mysql事务隔离级别与锁机制.pdf

    "深入理解Mysql事务隔离级别与锁机制" 事务隔离级别是数据库系统中的一种机制,用于解决多事务并发问题,使得事务之间的执行不受影响。这种机制可以分为四个级别:Read Uncommitted、Read Committed、Repeatable ...

    详解Mysql事务隔离级别与锁机制.doc

    详解Mysql事务隔离级别与锁机制 ...Mysql事务隔离级别与锁机制是数据库系统中的一种机制,用于解决多事务并发问题和数据并发访问的一致性问题。了解这些机制对数据库系统的设计和实现有重要的参考价值。

    MySQL数据库事务隔离级别详解

    MySQL数据库的事务隔离级别是数据库管理系统中用于控制事务处理中并发操作的重要机制。在多用户同时访问数据库的情况下,事务隔离级别能够确保数据的一致性和完整性,避免并发操作带来的各种问题,如脏读、不可重复...

    spring常用数据库事务传播属性和事务隔离级别1

    Spring 框架提供了一套完善的事务管理机制,其中包含了多种事务传播属性和事务隔离级别。这些特性使得在处理数据库操作时,能够更好地控制事务的边界和行为,从而确保数据的一致性和完整性。 首先,我们来看一下...

    mysql数据库事务隔离级别[参照].pdf

    事务隔离级别是数据库系统用来解决并发问题,保证数据正确性的一种策略。MySQL数据库提供了四种不同的事务隔离级别,它们分别是读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable ...

    深入理解Mysql事务隔离级别与锁机制.zip

    总的来说,深入理解MySQL的事务隔离级别和锁机制对于优化数据库性能、保证数据一致性以及解决并发问题具有重要意义。通过灵活运用这些知识,我们可以更好地设计和维护数据库系统,确保其稳定、高效地运行。

    数据库事务与隔离级别.docx

    数据库事务与隔离级别 数据库事务是指一系列操作的集合,作为一个单元执行,以维护数据库的一致性和完整性。事务必须具备四大特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性...

    数据库的隔离级别介绍

    以下是四种标准的事务隔离级别及其特点: 1. 未授权读取(Read Uncommitted): 这是最低的隔离级别,允许脏读取,但不允许更新丢失。在这个级别下,事务可能会读取到未提交的数据,存在数据不一致的风险。虽然...

Global site tag (gtag.js) - Google Analytics