zoukankan      html  css  js  c++  java
  • 数据库读写并发控制

    在数据库中,并发控制是指在多个用户/进程/线程同时对数据库进行操作时,如何保证事务的一致性和隔离性的,同时最大程度地并发。

    当多个用户/进程/线程同时对数据库进行操作时,会出现3种冲突情形:
    1. 读-读,不存在任何问题
    2. 读-写,有隔离性问题,可能遇到脏读(会读到未提交的数据) ,幻读(重复读)等。
    3. 写-写,可能丢失更新

    要解决冲突,一种办法是是锁,即基于锁的并发控制,比如2PL,这种方式开销比较高,而且无法避免死锁。

    多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。 这样在读操作不用阻塞写操作,写操作不用阻塞读操作的同时,避免了脏读和不可重复读

    乐观并发控制(OCC)是一种用来解决写-写冲突的无锁并发控制,认为事务间争用没有那么多,所以先进行修改,在提交事务前,检查一下事务开始后,有没有新提交改变,如果没有就提交,如果有就放弃并重试。乐观并发控制类似自选锁。乐观并发控制适用于低数据争用,写冲突比较少的环境。

    悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。
     
    总结:  

    悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

    乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

    两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

     
     

    事务没有隔离性会出现的问题:

    脏读:(同时操作都没提交的读取)

    脏读又称无效数据读出。一个事务读取另外一个事务还没有提交的数据叫脏读。

    例如:事务T1修改了一行数据,但是还没有提交,这时候事务T2读取了被事务T1修改后的数据,之后事务T1因为某种原因Rollback了,那么事务T2读取的数据就是脏的。

    解决办法:把数据库的事务隔离级别调整到READ_COMMITTED

    不可重复读:(同时操作,事务一分别读取事务二操作时和提交后的数据,读取的记录内容不一致)

    不可重复读是指在同一个事务内,两个相同的查询返回了不同的结果。

    例如:事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。 解决办法:把数据库的事务隔离级别调整到REPEATABLE_READ

    幻读:(和可重复读类似,但是事务二的数据操作仅仅是插入和删除,不是修改数据,读取的记录数量前后不一致)

    例如:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入(注意时插入或者删除,不是修改))了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样。这就叫幻读。

    解决办法:把数据库的事务隔离级别调整到SERIALIZABLE_READ

  • 相关阅读:
    阶段一-01.万丈高楼,地基首要-第3章 用户登录注册模块开发-3-13 实现用户信息在页面显示
    阶段一-01.万丈高楼,地基首要-第3章 用户登录注册模块开发-3-12 回顾cookie与session
    阶段一-01.万丈高楼,地基首要-第3章 用户登录注册模块开发-3-11 实现用户登录
    阶段一-01.万丈高楼,地基首要-第3章 用户登录注册模块开发-3-10 设置跨域配置实现前后端联调
    阶段一-01.万丈高楼,地基首要-第3章 用户登录注册模块开发-3-9 使用tomcat运行前端源码
    阶段一-01.万丈高楼,地基首要-第3章 用户登录注册模块开发-3-8 优化Swagger2显示
    阶段一-01.万丈高楼,地基首要-第3章 用户登录注册模块开发-3-6 整合Swagger2文档api
    Swift实现Touch ID验证
    Mac上phantomjs装了不能用的解决
    after modifying system headers, please delete the module cache at
  • 原文地址:https://www.cnblogs.com/lxk233/p/8639311.html
Copyright © 2011-2022 走看看