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

数据并发带来的各种情况

阅读更多

 

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

①脏读:事务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中的数据并发性异常.doc

    虽然使用数据集通过减少对数据库服务器的高花费的访问而提高了性能,但是它也带来了多个用户试图同时访问相同数据的可能性,由此引起数据并发性异常(data concurrency exception)。本文调查了数据并发性异常背后的...

    论文研究-在线BCI高速数据流的可预测并发实时传输.pdf

    以线程并发作为解决高速计算问题的切入点,首先将EEG信号分析任务分解为多个线程子任务,并通过缓冲区管理策略解决线程并发带来的协同问题,针对高速EEG数据流的复杂变化问题,采用自适应单向模糊推理的方法预测数据...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段04讲 利用CAS构造一个TryLock自定义显式锁-增强并发情况下.mp4  高并发编程第三阶段05讲 AtomicBoolean源码分析.mp4  高并发编程第三阶段06讲 AtomicLong源码分析.mp4  高并发编程第三阶段07...

    Java并发编程实战

    1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 性能问题 1.4 线程无处不在 第一部分 基础知识 第2章 线程安全性 2.1 什么是线程安全性 2.2 原子性 2.2.1 竞态条件 2.2.2 示例:延迟初始化...

    DataSet的数据并发异常处理

    虽然使用数据集通过减少对数据库服务器的高花费的访问而提高了性能,但是它也带来了多个用户试图同时访问相同数据的可能性,由此引起数据并发性异常(dataconcurrencyexception)。本文调查了数据并发性异常背后的...

    龙果java并发编程完整视频

    第11节了解多线程所带来的安全风险00:13:16分钟 | 第12节从线程的优先级看饥饿问题00:18:42分钟 | 第13节从Java字节码的角度看线程安全性问题00:25:43分钟 | 第14节synchronized保证线程安全的原理(理论层面)00...

    (牛客网C++课程)Linux 高并发Web服务器项目实战(带定时检测代码)

    3. 采用模拟 Proacto r的事件处理模式,利用线程池实现多线程机制,实现高并发通信,减少频繁创建和销毁线程带来的开销;(信号和互斥锁) 4. 主进程负责事件的读写,子线程负责业务逻辑——用有限状态机解析HTTP...

    Java 7并发编程实战手册

    java7在并发编程方面,带来了很多令人激动的新功能,这将使你的应用程序具备更好的并行任务性能。 《Java 7并发编程实战手册》是Java 7并发编程的实战指南,介绍了Java 7并发API中大部分重要而有用的机制。全书分为9...

    Java 并发编程实战

    1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 性能问题 1.4 线程无处不在 第一部分 基础知识 第2章 线程安全性 2.1 什么是线程安全性 2.2 原子性 2.2.1 竞态条件 2.2.2 示例:延迟初始化...

    java并发编程

    第11节了解多线程所带来的安全风险00:13:16分钟 | 第12节从线程的优先级看饥饿问题00:18:42分钟 | 第13节从Java字节码的角度看线程安全性问题00:25:43分钟 | 第14节sy nchronized保证线程安全的原理(理论层面)...

    Java并发编程原理与实战

    了解多线程所带来的安全风险.mp4 从线程的优先级看饥饿问题.mp4 从Java字节码的角度看线程安全性问题.mp4 synchronized保证线程安全的原理(理论层面).mp4 synchronized保证线程安全的原理(jvm层面).mp4 单例问题...

    并发容器和线程池,java并发编程3

    类,来感受⼀下JDK⾃带的并发集合带来的“快感”。 ConcurrentLinkedQueue是⼀个基于链接节点的⽆界线程安全队列,它采⽤先进先出的规则对节点 进⾏排序,当我们添加⼀个元素的时候,它会添加到队列的尾部,当我们...

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段04讲 利用CAS构造一个TryLock自定义显式锁-增强并发情况下.mp4  高并发编程第三阶段05讲 AtomicBoolean源码分析.mp4  高并发编程第三阶段06讲 AtomicLong源码分析.mp4  高并发编程第三阶段07...

    Java 并发编程原理与实战视频

    第11节了解多线程所带来的安全风险00:13:16分钟 | 第12节从线程的优先级看饥饿问题00:18:42分钟 | 第13节从Java字节码的角度看线程安全性问题00:25:43分钟 | 第14节synchronized保证线程安全的原理(理论层面) ...

    数据库九(并发控制)

    并发操作带来数据不一致性: 丢失修改:两个事务同时读入同一个数据并修改,结果T2的提交破坏了T1提交的结果 不可重复读:事务T1读取数据后,事务T2执行更新操作,导致T1无法再现前一次读取结果 读脏数据:事务T1...

    龙果 java并发编程原理实战

    第11节了解多线程所带来的安全风险00:13:16分钟 | 第12节从线程的优先级看饥饿问题00:18:42分钟 | 第13节从Java字节码的角度看线程安全性问题00:25:43分钟 | 第14节synchronized保证线程安全的原理(理论层面) ...

    高并发系统数据幂等的解决方案

    经常遇到数据重复插入、重复更新、消息重发发送等等问题,因为应用系统的复杂逻辑以及网络交互存在的不确定性,会导致这一重复现象,但是有些逻辑是需要有幂等特性的,否则造成的后果会比较严重,例如订单重复创建,...

Global site tag (gtag.js) - Google Analytics