`
xvm03
  • 浏览: 144462 次
  • 来自: ...
社区版块
存档分类
最新评论

数据并发带来的各种情况

阅读更多

 

一、数据并发带来的各种情况 

①脏读:事务A读到事务B尚未提交的数据,并基于这个数据进行后续操作

②不可重复读:事务A读取数据后,被事务B修改或删除,事务A再次读取时前后两次读取的数据不一致

③幻像读:事务A读取数据后,事务B新增了数据,事务A再次读取是前后两次读取的数据不一致


不可重复读和幻想读的区别:

幻象读和不可重复读是两个容易混淆的概念,前者是指读到了其它已经提交事务的新增数据,而后者是指读到了已经提交事务的更改数据(更改或删除),为了避免这两种情况,采取的对策是不同的,防止读取到更改数据,只需要对操作的数据添加行级锁,阻止操作中的数据发生变化,而防止读取到新增数据,则往往需要添加表级锁——将整个表锁定,防止新增数据(Oracle使用多版本数据的方式实现)。

④第一类更新丢失:事务A和事务B同时访问同一个数据,事务B先提交修改,事务A回滚操作。导致事务B的修改丢失

⑤第二类更新丢失:事务A和事务B同时访问同一个数据,事务B先提交修改,事务A再提交。导致事务B的修改被覆盖

第一类更新丢失是很严重的操作,如果控制不当,可能导致在一个长时间的大型事务中,所有的操作都被回滚。所以所有的数据库都不支持这种并发情况。

二、数据库的锁机制

从锁的作用范围来分,可以分为:行级锁和表级锁
从锁的排他性来分,可以分为:共享锁和独占锁(排他锁),
其中共享锁允许共享,但阻止独占锁。独占锁不但不允许共享锁,且不允许其它独占锁


于是组合起来就有:

①行共享锁:允许多个会话共享锁定的行数据,但不允许对这些行的独占锁。例如select ...for update

②行独占锁:对行进行独占,不允许其它的共享锁(表,行)、独占锁(表,行)和表共享行独占锁。例如insert,update

③表共享锁:允许多个会话共享表数据,但不允许其它的独占锁(表,行)、表共享行独占锁。可以实现表级事务一致性

④表独占锁:对表进行独占,不允许其它的共享锁(表,行)、读占锁(表,行)和表共享行独占锁。达到序列化操作级别

⑤表共享行独占锁:允许多个会话共享表数据,但同一时刻只能有一个行独占锁。可以达到数据共享同时防止脏读、不可重复读、幻像读

表共享锁定可以让会话具有对表事务级一致性访问,因为其它会话在你提交或者回溯该事务并释放对该表的锁定之前不能更改这个被锁定的表(因为要修改表的记录,就必须获得行独占锁,但是共享锁会阻止独占锁的获取,这样原来其它正在读取表记录的事务就不会出现脏读、不可重复读、幻像读的情况了); 

表共享行独占锁与其不同则是多了一个行独占,这样效率更高。

三、事务隔离级别

尽管数据库为用户提供了锁的DML操作方式,但直接使用锁管理是非常麻烦的,因此数据库为用户提供了自动锁机制。只要用户指定会话的事务隔离级别,数据库就会分析事务中的SQL语句,然后自动为事务操作的数据资源添加上适合的锁。此外数据库还会维护这些锁,当一个资源上的锁数目太多时,自动进行锁升级以提高系统的运行性能,而这一过程对用户来说完全是透明的

下面是ANSI ISO92定义的4个事务隔离级别以及对应的对数据并发的处理


READ COMMITITED:不允许读取未提交的数据,但可以读取已提交的数据。所以可能出现不可重复读、和幻像读(读的过程依然可以被修改、增加、删除)

 
REPEATABLE READ:通过行锁定,在读的数据不允许其它进程修改。确保已读取的数据不被修改、删除(不可重复读)但无法阻止其它进程写入新数据,所以不能确保读取到新的数据(幻像读)
 
SERIALIZABLE:通过表锁定,彻底禁止读取期间其它进程的修改、删除(屏蔽不可重复读)和增加(屏蔽幻像读)
 
但是不管是那种隔离级别,对第一类丢失更新都是不能接收的 

解决方案:为了避免上面出现的几种情况,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。 
  ● 未授权读取,也称为读未提交(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。 
  ● 授权读取,也称为读提交(Read Committed):允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。 
  ● 可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。 
  ● 序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。 
  隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。 

 

分享到:
评论

相关推荐

    DataSet的数据并发异常处理收集.pdf

    然而,这种离线操作也带来了数据并发性异常的风险。 描述中提到,数据并发性异常通常发生在多个用户尝试同时访问和修改同一数据集中的数据时,由于数据集存储的是数据库某一时刻的快照,如果在用户A修改数据的同时...

    帆软7.0.4并发补丁

    在企业环境中,特别是在大数据量处理和高并发访问的情况下,系统的并发性能至关重要。这款补丁的出现,旨在提升系统在高并发情况下的稳定性和效率,确保用户能够流畅地进行数据查询、分析和报表制作。 首先,我们...

    数据库并发控制,封锁,并发调度学习攻略

    通过合理应用这两种类型的锁,可以在不影响并发性能的前提下,有效防止并发操作所带来的问题。 ### 活锁与死锁 #### 活锁 活锁发生在多个事务请求相同的资源时,由于某些事务总是让位于其他事务,导致某些事务...

    oracle 高并发高负载情况下常见的3种性能问题

    但在高并发环境下,这种频繁的调整会导致某些内存操作(如latch/mutex的获取和释放)耗时增加,进而可能引发各种latch/mutex的竞争。 **引发此问题的原因可能包括:** 1. **软件缺陷**:虽然存在软件缺陷的可能性...

    深入理解并发编程

    Linux大神Paul McKenney的作品《深入理解并发编程》对并发编程的各种概念进行了详细介绍。该书深入探讨了内存屏障(Memory Barriers)和互斥锁(Mutual Exclusion, mutex)等关键技术。内存屏障是一种同步机制,可以...

    高并发系统设计.pdf

    然而,缓存的使用也带来了一定的挑战,如数据过期策略、缓存穿透和缓存雪崩等问题,需要合理设计和管理。 此外,异步处理是另一种应对高并发的有效手段。在某些场景下,系统可以先返回结果,然后在后台处理任务,待...

    Java并发实战

    Java作为一门成熟的编程语言,其在并发控制方面提供了丰富而强大的工具和API,但是这也给开发者带来了一定的学习和使用难度。该书的目的就是帮助读者通过实战和案例分析,快速掌握Java并发编程的核心概念和最佳实践...

    高并发和并发编程

    高并发是指系统在同一时间处理大量请求的能力,这在Web服务、分布式系统以及大数据处理等场景中尤其重要。而并发编程则是实现高并发的基础,它涉及到如何在多线程环境下有效地管理计算资源,以提高系统性能和响应...

    并发容器的原理,7大并发容器详解、及使用场景

    并行容器是 Java 多线程编程中不可或缺的一部分,它们...开发者应根据业务场景选择合适的容器,避免全局锁带来的性能损失,充分利用并发容器提供的高级并发控制机制,确保在多线程环境下数据的一致性和程序的高效运行。

    数据库并发控制sqlserver2000

    SQL Server 2000通过其强大的并发控制机制,有效地解决了并发操作中可能出现的各种问题,保证了数据的一致性和完整性。通过合理地利用封锁机制和遵循相应的封锁协议,可以在保持数据库高并发的同时,避免因并发操作...

    CsGo并发流程控制框架

    线程池是一种高效的线程管理方式,它可以复用已存在的线程,避免频繁创建和销毁线程带来的开销。C#中的`ThreadPool`类提供线程池服务,通过`QueueUserWorkItem`方法提交任务到线程池,适合执行大量短生命周期的任务...

    C++ 并发编程中文版

    原子操作是无锁编程的基础,它是并发编程中的高级话题,可以有效减少因使用锁而带来的开销。 书中还有专门的章节讲解了 C++ 内存模型和原子类型操作。在多线程环境中,多个线程可能会操作同一块内存,这就需要一种...

    01-并发编程之深入理解JMM&并发三大特性(一).pdf

    并行是并发的一种特殊情况,或者说,并发是并行的一个更为广泛的术语。 并发编程中的三大特性:可见性、有序性和原子性,是多线程编程中主要的并发问题来源。这些特性是理解和规避并发编程中Bug的关键。 可见性...

    并发与控制

    为了应对上述问题,数据库系统通常采用各种并发控制机制来保证数据的一致性和事务的隔离性。常见的并发控制方法包括: 1. **封锁**:通过加锁机制来防止多个事务同时访问同一数据项。封锁分为排他锁(X锁)和共享锁...

    高并发的常见应对方案

    ### 高并发的常见应对方案 #### 一、理解高并发 在当今互联网时代,随着用户数量的激增和技术的进步,高并发已经成为了一个常见的...通过上述方法,我们可以有效地应对高并发带来的挑战,保障系统的稳定性和高效性。

    Java并发编程学习笔记

    Java并发包(java.util.concurrent)也提供了丰富的并发工具,如线程安全集合(如ConcurrentHashMap)、阻塞队列(如ArrayBlockingQueue)、信号量(Semaphore)、并发集合(如CopyOnWriteArrayList)和各种执行器...

    Java并发编程实践.pdf

    在传统的多线程环境下,需要共享某些数据,但为了避免竞争条件引致数据出现不一致的情况,某些代码段需要变成基于锁(Lock based)的原子操作去执行。Amino提供了无锁数据结构,如LockFreeQueue等,以避免竞争条件,...

    数据库并发控制

    #### 一、数据并发产生的问题 在多用户环境下,尤其是在网络环境中,允许多个用户同时访问数据库系统是非常常见的需求。比如,飞机订票系统、银行系统等,这些系统的典型特征就是在同一时刻能够支持数百个并发运行...

    java并发实战中文文档

    4. **并发集合**:Java并发集合如`ConcurrentHashMap`、`CopyOnWriteArrayList`和`ConcurrentLinkedQueue`等,是为并发环境优化过的数据结构。它们内部实现了线程安全,能够在不引入全局锁的情况下实现高效并发操作...

Global site tag (gtag.js) - Google Analytics