`

关于数据库事务、隔离级别、锁的理解与整理

阅读更多

事务(Transaction)

数据库的事务是数据库并发控制的基本单位,一组操作的集合、序列。要么都执行,要么都不执行,是一个不可分割的整体。比如银行的转账,钱从一个账户转移到另一个账户,账户A扣钱账户B加钱,要么都执行,要么都不执行。不可能A扣了钱B没有加钱,也不可能A没扣钱B却加了钱。

 

数据库的事务应当具有以下四种特性:

 

Atomic(原子性)

事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。

Consistency(一致性)

只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。

Isolation(隔离性)

事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。

同时,并行事务的修改必须与其他并行事务的修改相互独立。

事务的隔离性一般由事务的锁来进行控制。

Durability(持久性)

事务结束后,事务处理的结果必须能够得到固化。

 

数据库的事务和程序的线程有相似的地方:

1.线程之间共享同一片资源,而事务共享的则是数据库内的数据。

2.多线程的意义在于并发执行,提高效率;事务并发执行也能提高程序与数据库交互的效率。

因此如何使用事务与事务相互之间的隔离级别,直接影响了数据库的并发性和数据的准确性。我们在设计事务和选择隔离级别时这些是应该要考虑的。

 

选择完隔离级别与设计完事务之后,在使用过程中常常会遇到以下几种情况:

 

1.更新丢失(Lost update):两个事务同时更新,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。

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

3.不可重复读取(Non-repeatable Reads):一个事务两次读取,但在第二次读取前另一事务已经更新了。

4.虚读(Phantom Reads):一个事务两次读取,第二次读取到了另一事务插入的数据。

5.两次更新问题(Second lost updates problem):两个事务都读取了数据,并同时更新,第一个事务更新失败。

 

 

 

隔离级别(低->高)

 

●   未授权读取(Read Uncommitted)

允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。

 

●   授权读取(Read Committed)

允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

 

●   可重复读取(Repeatable Read)

禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。

 

●   序列化(Serializable)

提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

 

 

个人觉得隔离级别的翻译不是很好理解,直接按照英语的意思理解更方便。

 

 

 

eg:

 

假设账户c1有1000元,c2有1000元,c3有1000元

操作员u1执行一次转账事务m1从c1转移500元到c2,再从c1的余额中转移50%元平均分配到 c1 c2 c3 c4 c5余额中

操作员u2执行一次转账事务m2从c2转移1000元到c1

操作员u3执行一次转账事务m3从c1转移200元到c2

操作员u4开户c4

 

 

账户表为T_C,其包含字段为 账户名称cname 余额money

记录为{c1,1000},{c2,1000}

事务m1的操作包括,读c1,读c2,写c1,写c2,提交c1c2,读c1,读c3,写c3,写c3,提交c1c3

事务m2的操作包括,读c2,读c1,写c2,写c1,提交c1c2

事务m3的操作包括,读c1,读c2,写c1,写c2,提交c1c2

事务m4的操作包括,写c4,提交c4

 

 

1.若未授权读取ReadUncommitted

m1读c1,c2,写了c1但没写c2 此时m2不可以写c2,可以读取c1和c2,但是c2是脏读。隔离级别使用了“排他写锁”。

 

2.若授权读取ReadCommitted

m1读c1,c2,写了c1但没写c2 此时m2不可以写c2,可以读取c1,不能读取c2,因为c2是脏读。隔离级别使用了“排他写锁”。

m1读写了c1,c2,提交c1c2,m3提交了c1c2 此时m1准备第二次c1是允许的。隔离级别使用了“瞬间共享读锁”。(但由于第二次读产生了不可重复读的问题,事务1脱力了元自行,因为逻辑上看事务1中被插入了3,影响了c1的余额50%的计算。)

 

3.若可重复读取RepeatableRead

m1读c1,c2,写了c1但没写c2 此时m2不可以写c2,可以读取c1,不能读取c2,因为c2是脏读。隔离级别使用了“排他写锁”。

m1读写了c1,c2,提交c1c2,m4提交了c4 此时m3是能读不能写c1并更新提交的。此时m4是能读能能插入c4的。隔离级别使用了“共享读锁”。(和ReadCommitted比RepeatableRead区别对已经提交的事务可以进行读,但不能写,但是同一张表可以插入新的记录。)

 

4.序列化Serializable

任何事务都只能等前一事务完全执行完再执行。 但是失去了并发性。

 

对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

 

选取数据库的隔离级别时,应该注意以下几个处理的原则:

首先,必须排除“未授权读取”,因为在多个事务之间使用它将会是非常危险的。事务的回滚操作或失败将会影响到其他并发事务。第一个事务的回滚将会完全将其他事务的操作清除,甚至使数据库处在一个不一致的状态。很可能一个已回滚为结束的事务对数据的修改最后却修改提交了,因为“未授权读取”允许其他事务读取数据,最后整个错误状态在其他事务之间传播开来。

其次,绝大部分应用都无须使用“序列化”隔离(一般来说,读取幻影数据并不是一个问题),此隔离级别也难以测量。目前使用序列化隔离的应用中,一般都使用悲观锁,这样强行使所有事务都序列化执行。

 

       剩下的也就是在“授权读取”和“可重复读取”之间选择了。我们先考虑可重复读取。如果所有的数据访问都是在统一的原子数据库事务中,此隔离级别将消除一个事务在另外一个并发事务过程中覆盖数据的可能性(第二个事务更新丢失问题)。这是一个非常重要的问题,但是使用可重复读取并不是解决问题的唯一途径。

 

 

SQL语句可以使用SET TRANSACTION ISOLATION LEVEL来设置事务的隔离级别。

如:SET TRANSACTION ISOLATION LEVEL   Read Committed。

若要在应用程序中使用更严格或较宽松的隔离级别,可以通过使用   set transaction isolation level语句设置会话的隔离级别,来自定义整个会话的锁定。指定隔离级别后,sql server会话中所有select语句的锁定行为都运行于该隔离级别上,并一直保持有效直到会话终止或者将隔离级别设置为另一个级别。

 

 

锁(并发控制的手段)

 

独占锁(排他锁) 只允许一个事务访问数据 

共享锁 允许其他事务继续使用锁定的资源 

更新锁

 

锁就是保护指定的资源,不被其他事务操作,锁定的资源包括行、页、簇、表和数据库。为了最小化锁的成本,SQL Server自动地以与任务相应等级的锁来锁定资源对象。锁定比较小的对象,例如锁定行,虽然可以提高并发性,但是却有较高的开支,因为如果锁定许多行,那么需要占有更多的锁。锁定比较大的对象,例如锁定表,会大大降低并发性,因为锁定整个表就限制了其他事务访问该表的其他部分,但是成本开支比较低,因为只需维护比较少的锁。

 

  设置事务级别:SET TRANSACTION ISOLATION LEVEL

开始事务:begin tran 

提交事务:COMMIT

回滚事务:ROLLBACK 

创建事务保存点:SAVE TRANSACTION savepoint_name 

回滚到事务点:ROLLBACK TRANSACTION savepoint_name

 

 


 

3
4
分享到:
评论
4 楼 johnicesea 2011-08-02  
wangcfxbg 写道
johnicesea 写道
哈哈 不错不错。

你好像很早就用这个了嘛

3 楼 wangcfxbg 2011-08-02  
johnicesea 写道
哈哈 不错不错。

你好像很早就用这个了嘛
2 楼 suhuanzheng7784877 2011-08-02  
至少我赞一个
1 楼 johnicesea 2011-08-02  
哈哈 不错不错。

相关推荐

    JavaAnd数据库事务[整理].pdf

    数据库系统提供了不同的事务隔离级别来平衡并发性能和数据一致性。常见的隔离级别包括: 1. 读未提交(Read Uncommitted):允许读取未被其他事务提交的数据,可能导致脏读。 2. 读已提交(Read Committed):每次...

    面,试材料整理,关于数据库

    了解事务的四种隔离级别(读未提交、读已提交、可重复读、串行化)以及可能导致的问题,如脏读、不可重复读和幻读。 5. **索引**:索引可以显著提升查询速度,但会占用额外的存储空间并可能影响写操作。B树、B+树和...

    数据库原理与应用实验15_整理.pdf

    【实验十五】主要探讨了数据库...通过这个实验,学生能够理解数据库事务的基础,为后续的并发控制和数据库管理系统的学习打下基础。同时,实验也提醒了学生在实际开发中正确管理和使用事务以确保数据的准确性和完整性。

    Java+数据库笔试和学习整理

    4. **数据库事务**:了解ACID属性(原子性、一致性、隔离性、持久性),以及事务的提交、回滚和隔离级别。 5. **数据库性能优化**:包括查询优化、存储优化、索引策略和数据库调优技巧。 6. **常见数据库系统**:如...

    数据库各种实验整理、

    学习如何利用锁定机制、乐观锁和悲观锁,以及事务的ACID(原子性、一致性、隔离性和持久性)属性来确保数据的一致性。 7. **数据库性能监控与调优** 实验中会涉及数据库性能监控,包括跟踪SQL查询性能、分析慢查询...

    SQL Server 2000 70-229中文版部分答案解析(整理版)下

    70-229考试主要测试考生对SQL Server数据库管理和性能调优的理解,特别是关于死锁和事务隔离级别的概念。 死锁是两个或多个事务在等待对方释放资源而形成的僵局。在描述中提到的例子中,线程T1持有Supplier表的排他...

    数据库实验数据和公共数据库

    10. **并发控制与隔离级别**:在多用户环境中,数据库需要管理多个事务同时访问数据。不同的隔离级别(如读未提交、读已提交、可重复读和串行化)决定了事务间的相互影响程度。 通过这些知识点的学习和实践,你可以...

    数据库系统工程师04-10历年试题分析与解答1 pdf

    7. **数据库并发控制**:例如多用户环境下如何避免脏读、不可重复读和幻读等问题,理解并掌握各种锁定机制和事务隔离级别。 8. **数据库复制与集群**:主从复制、分布式数据库和数据库集群的原理和应用,如何提高...

    【整理】数据库面试题索引sql优化+数据库SQL优化总结之百万级数据库优化

    4. **事务与并发控制**:在高并发环境下,事务的隔离级别、死锁检测和解决策略都是重要的话题。 5. **性能监控与调优工具**:学习如何使用如MySQL的Performance Schema、Oracle的Automatic Workload Repository ...

    MySQL数据库高级工程师-面试题-MySQLDBA面试题03-风哥整理面试必过.rar

    3. **事务处理**:理解ACID(原子性、一致性、隔离性、持久性)特性,掌握四种事务隔离级别:读未提交、读已提交、可重复读、串行化,以及它们的并发问题,如脏读、不可重复读、幻读等。 4. **锁机制**:了解行级锁...

    DB2数据库调整数据库性能

    - **并发控制**:合理设置锁策略和事务隔离级别,以平衡读写操作之间的冲突。 - **硬件升级**:在必要时考虑增加CPU核心数、扩展RAM或更换更快的存储设备等硬件升级措施。 ### 四、DB2数据库性能调整的具体实践 ##...

    数据库-简答题整理.docx

    【数据库简答题整理】 在IT领域,数据库是管理和存储数据的核心工具。以下是一些关于数据库的重要知识点: 1. **事务**: - 事务是数据库操作的基本单位,它确保一组操作要么全部完成,要么全部不完成,以维护...

    [整理版]tuxedo与数据库互连.doc

    这种方式降低了客户端与数据库之间的直接依赖,使得系统更易于管理和维护,同时能够更好地支持并发处理和事务管理。 TUXEDO服务端可以与多种数据库系统集成,包括INFORMIX。在具体实现中,TUXEDO服务端可以在同一台...

    mysql数据库的相关学习整理汇总.zip

    5. **事务处理**:InnoDB存储引擎支持ACID(原子性、一致性、隔离性、持久性)特性,理解事务的开始、提交、回滚以及四种隔离级别对于确保数据的一致性至关重要。 6. **备份与恢复**:掌握如何进行数据库备份...

    数据库组成原理答案

    《数据库组成原理》一书深入探讨了数据库的核心概念和技术,旨在帮助学生和自学者理解数据库的工作原理和设计思想。这里,我们将根据书中的内容,结合提供的"数据库实践习题解答",详细解析一些关键知识点。 1. **...

    数据库工具-数据量抽取&数据库阻塞探测

    一旦找到阻塞,可以通过优化SQL查询、调整事务隔离级别、合理分配资源或设计更好的并发控制策略来解决。 在整理索引方面,索引是数据库中的一个重要组成部分,它们加速了数据检索速度。不过,不当的索引管理可能...

    数据库实验报告模板

    3. 在处理并发问题时,对事务的隔离级别理解不足。通过学习相关文档,理解了READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE四种隔离级别的差异。 六、未解决的问题 尽管大部分问题已解决,但仍...

    北邮数据库实验三[整理].pdf

    此外,还需要通过多客户端并发操作来体验并发控制和事务隔离级别,以及了解当客户端突然关闭时对事务的影响。 总的来说,这个实验涵盖了数据库设计、数据完整性、索引优化、触发器应用和事务处理等多个关键领域,...

    数据库课程设计:组织MBTI人格测试系统.zip

    4. **安全性与权限管理**:数据库需要设置不同级别的访问权限,如读、写和执行,以保护用户数据的安全。此外,可能还需要实现身份验证和授权机制。 5. **性能优化**:随着用户数量的增长,可能需要对数据库进行优化...

Global site tag (gtag.js) - Google Analytics