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

数据库事务小记

阅读更多

事务的四个属性

     原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性 (durability)。

1. 原子性 (Atomic)
    最重要的原则,也是最容易理解的原则。被事务管理的所有方法,要么一起被提交,要么一起回滚。

2. 一致性 (Consistency)
    事务在系统完整性中实施一致性,如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于新有效状态。如果在事务中出现错误,那么系统中的所有变化 将自动地回滚,系统返回到原始状态。

3. 隔离性 (Isolation)
    在隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在 系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数 据。重要的是,在隔离状态执行事务,系统的状态有可能是不一致的,在结束事务前,应确保系统处于一致状态。但是在每个单独的事务中,系统的状态可能会发生 变化。如果事务不是在隔离状态运行,它就可能从系统中访问数据,而系统可能处于不一致状态。通过提供事务隔离,可以阻止这类事件的发生。

4. 持久性 (Durability)
    持久性意味着一旦事务执行成功,在系统中产生的所有变化将是永久的。应该存在一些检查点防止在系统失败时丢失信息。甚至硬件本身失败,系统的状态仍能通过 在日志中记录事务完成的任务进行重建。

数据库锁概念:
    
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两 种基本的锁类型来对数据库的事务进行并发控制。
    从程序员的角度看,锁分为以下两种类型: 
    1.乐观锁(Optimistic Lock) 
    乐观锁假定在处理数据时,不需要在应用程序的代码中做任何事情就可以直接在记录上加锁、即完全依靠数据库来管理锁的工作。一般情况下,当执行事务 处理时SQL Server会自动对事务处理范围内更新到的表做锁定。 
    2.悲观锁(Pessimistic Lock) 
    悲观锁对数据库系统的自动管理不感冒,需要程序员直接管理数据或对象上的加锁处理,并负责获取、共享和放弃正在使用的数据上的任何锁。


事务隔离级别:
    
一个事务必须与其它事务进行隔离的程度。较低的隔离级别可以增加并发,但代价是降低数据的正确性。相反,较高的隔离级别可以确保数据的正确 性,但可能对并发产生负面影响。

数据库并发操作存在的异常情况:
     1. 更新丢失(Lost update):两个事务都同时更新一行数据但是第二个事务却中途失败退出导致对数据两个修改都失效了这是系统没有执行任何锁操作因此并发事务并没有被隔 离开来

     2. 脏读取(Dirty Reads):一个事务开始读取了某行数据但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险很可能所有操作都被回滚

3. 不可重复读取 (Non-repeatable Reads):一个事务对同一行数据重复读取两次但是却得到了不同结果。例如在两次读取中途有另外一个事务对该行数据进行了修改并提交

     4. 两次更新问题 (Second lost updates problem):无法重复读取特例,有两个并发事务同时读取同一行数据然后其中一个对它进行修改提交而另一个也进行了修改提交这就会造成第一次写操作失 效

     5. 幻读(Phantom Reads):也称为幻像(幻影)。事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有另外一个事务插入数据造成的。

     为了避免上面出现几种情 况在标准SQL规范中定义了4个事务隔离级别 ,不同隔离级别对事务处理不同 。

     1. 未授权读取(Read Uncommitted):也称未提交读。允许脏读取但不允许更新丢失,如果一个事务已经开始写数据则另外一个数据则不允许同时进行写操作但允许其他事务 读此行数据。该隔离级别可以通过“排他写锁”实现。事务隔离的最低级别,仅可保证不读取物理损坏的数据。与READ COMMITTED 隔离级相反,它允许读取已经被其它用户修改但尚未提交确定的数据。

     2. 授权读取(Read Committed):也称提交读。允许不可重复读取但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现,读取数据的事务允许其他事务继续访 问该行数据,但是未提交写事务将会禁止其他事务访问该行。SQL Server 默认的级别。在此隔离级下,SELECT 命令不会返回尚未提交(Committed) 的数据,也不能返回脏数据。

     3. 可重复读取 (Repeatable Read):禁止不可重复读取和脏读取。但是有时可能出现幻影数据,这可以通过“共享读锁”和“排他写锁”实现,读取数据事务将会禁止写事务(但允许读事 务),写事务则禁止任何其他事务。在此隔离级下,用SELECT 命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。

     4.  序列化(Serializable):也称可串行读。提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过 “行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作事务访问到。事务隔离的最高级别,事务之间完全隔离。如果事务 在可串行读隔离级别上运行,则可以保证任何并发重叠事务均是串行的。

 

     隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
     通过前面的介绍已经知道,通过选用不同的隔离等级就可以在不同程度上避免前面所提及的在事务处理中所面临的各种问题。所以,数据库隔离级别的选取就显得尤为重要,在选取数据库的隔离级别时,应该注意以下几个处理的原则:
     首先,必须排除“未授权读取”,因为在多个事务之间使用它将会是非常危险的。事务的回滚操作或失败将会影响到其他并发事务。第一个事务的回滚将会完全将其他事务的操作清除,甚至使数据库处在一个不一致的状态。很可能一个已回滚为结束的事务对数据的修改最后却修改提交了,因为“未授权读取”允许其他事务读取数据,最后整个错误状态在其他事务之间传播开来。
     其次,绝大部分应用都无须使用“序列化”隔离(一般来说,读取幻影数据并不是一个问题),此隔离级别也难以测量。目前使用序列化隔离的应用中,一般都使用悲观锁,这样强行使所有事务都序列化执行。
     剩下的也就是在“授权读取”和“可重复读取”之间选择了。我们先考虑可重复读取。如果所有的数据访问都是在统一的原子数据库事务中,此隔离级别将消除一个事务在另外一个并发事务过程中覆盖数据的可能性(第二个事务更新丢失问题)。这是一个非常重要的问题,但是使用可重复读取并不是解决问题的唯一途径。
     假设使用了“版本数据”,Hibernate会自动使用版本数据。Hibernate的一级Session缓存和版本数据已经为你提供了“可重复读取隔离”绝大部分的特性。特别是,版本数据可以防止二次更新丢失的问题,一级Session缓存可以保证持久载入数据的状态与其他事务对数据的修改隔离开来,因此如果使用对所有的数据库事务采用授权读取隔离和版本数据是行得通的。
     “可重复读取”为数据库查询提供了更好的效率(仅对那些长时间的数据库事务),但是由于幻影读取依然存在,因此没必要使用它(对于Web应用来说,一般也很少在一个数据库事务中对同一个表查询两次)。

 

隔离级别 更新丢失 脏读取 重复读取 幻读
未授权读取 N Y Y Y
授权读取 N N Y Y
可重复读取 N N N Y
串行 N N N N

分享到:
评论

相关推荐

    VC数据库编程小记ADO访问SQL Server2005

    在进行 VC 数据库编程的过程中,使用 ADO(ActiveX Data Objects)访问 SQL Server2005 是一个非常实用的技术。ADO 作为 Microsoft 提供的一套用于访问数据库的对象模型,它基于 OLE DB 技术,提供了更高级别的接口...

    android应用登录模块访问mysql数据库小记.pdf

    在Android应用开发中,构建一个登录模块并连接到MySQL数据库是一项常见的需求,特别是在需要处理用户...对于其他开发者而言,这篇小记提供了一个实践性的参考,帮助他们避免遇到类似的问题,顺利地构建自己的登录模块。

    Sqlite数据库sqlite3命令小记.txt

    ### Sqlite数据库sqlite3命令小记 #### 一、引言 SQLite 是一款轻量级的数据库管理系统,它被广泛应用于各种应用场景中,特别是在移动设备和嵌入式系统上。SQLite 不仅支持标准的 SQL 语法,还提供了一系列实用的...

    数据库保存图片及显示

    数据库保存图片及显示是数据库应用中的一个重要环节,尤其在网页开发、内容管理系统或者社交媒体平台中。这个主题主要涉及如何将图片数据存储到数据库中,并在需要时正确地展示出来。以下是对这一知识点的详细说明:...

    java小记.rar

    开发者可能会在笔记中分享如何创建数据库连接池、事务管理策略以及如何优化SQL查询。 MVC(Model-View-Controller)架构模式是Java Web开发中的常见设计模式,用于分离业务逻辑、数据模型和用户界面。Spring MVC或...

    android开发小记

    在“android开发小记”这个主题中,我们可以深入探讨Android应用程序开发的相关知识,特别是通过查看提供的压缩文件中的代码示例。这些文件名如lesson_8_code.zip至lesson_20_codel.zip,以及不同的Mp3Player版本,...

    【咬人草小记,阅读附答案】 咬人草小记阅读答案.docx

    这篇文章《咬人草小记》便是对这种植物的描述,以及作者与它亲密接触后的体验与思考。 文章的开始,是一段友人的警告:“这草,你可不能碰!”正是这句话,将作者的注意力引向了这种奇特的生物。咬人草的外表并...

    MYSQL学习资料

    MySQL数据库扩展小记 mysql架构方案 MySQL水平分区表实际操作总结 Mysql水平分表 mysql水平分表和垂直分表和数据库分区 sysbench mysql 坚持不懈 sysbench安装和使用 SHOW INNODB STATUS 探秘 体验Innodb with ...

    Linux boost库安装、编译问题小记

    环境: Linux s12084 2.6.9-67.ELsmp #1 SMP Wed ...小记一下。以备以后参考。  boost 库做得真好。在windows 平台, linux 平台下编译都很顺利。hp aCC 也宣称对 boost 1.35 完全支持 。  全部编译是很痛苦的过程

    sql loader用法小记

    这篇“sql loader用法小记”可能是博主对SQL Loader使用经验的总结和分享,虽然描述中没有具体信息,但从标签“源码”和“工具”可以推断,内容可能涉及到SQL Loader的基本操作、配置文件以及可能遇到的问题。...

    SQL学习小记

    标题 "SQL学习小记" 暗示了这篇博客文章主要关注的是SQL语言的学习和实践。SQL(Structured Query Language)是用于管理和处理关系数据库的标准编程语言。以下是对这个主题的详细探讨: SQL基础: 1. 数据类型:SQL...

    C++编程小记,经典收藏

    ### C++11 新特性详解 #### 一、Auto 关键字的新用途 - **旧用途**:在C++11之前,`auto`关键字主要用于指定变量的存储期。 - **新用途**:C++11引入了类型推断的概念,`auto`变成了一个类型占位符,用于告诉...

    随笔小记.doc

    随笔小记.doc

    御风小记账本

    在实际使用中,【御风小记账本】可能会使用本地数据库如SQLite来存储用户数据,SQLite是一个轻量级的、无服务器、零配置的嵌入式SQL数据库,非常适合用于桌面应用程序。用户数据的读写操作可以通过Delphi的ADO...

    我的日常小记:spring以及mybatis最终源码

    在本项目中,Spring可能还用于配置数据库连接、事务管理等,确保数据操作的完整性和一致性。 其次,MyBatis作为数据访问层的解决方案,与Spring的集成使得数据操作更为便捷。MyBatis允许开发者直接编写SQL,将SQL...

    GeoStudio学习小记.pdf

    GeoStudio学习小记

    Redis小记

    **Redis小记** Redis,全名Remote Dictionary Server,是一款高性能的键值对存储系统,常被用作数据库、缓存和消息中间件。其非关系型数据存储方式、高效的内存管理以及丰富的数据结构使得它在现代互联网应用中扮演...

    数据字典-小记及用户部分1

    数据字典是数据库设计的重要组成部分,它记录了系统中各个数据元素的详细信息,包括数据的名称、描述、数据类型、长度以及可能的取值范围等。以下是对标题"数据字典-小记及用户部分1"中所提及的数据元素进行的详细...

Global site tag (gtag.js) - Google Analytics