zoukankan      html  css  js  c++  java
  • 数据库事务隔离

    简介

    1. 事务是要保证一组数据库操作,要么全成功,要么全失败。

    2. 在MySQL中,事务支持是在引擎层实现的

    3. MySQL原生的MyISAM引擎是不支持事务的,InnoDB是支持事务的

    4. 事务的特性ACID

      • Atomicity:原子性
      • Consistency:一致性
      • Isolation:隔离性
      • Durability:持久性

    隔离性

    三类问题

    1. 脏读:读到了未提交的数据

    脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

    2. 不可重复读:前后多次读取,数据内容不一致

    是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)

    3. 幻读:前后多次读取,数据总量不一致

    在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。

    MySQL、ORACLE、PostgreSQL等成熟的数据库,出于性能考虑,都是使用了以乐观锁为理论基础的MVCC(多版本并发控制)来实现。


    数据库事务隔离级别

    首先要明确一点,隔离的越严实,效率就越低。因此很多时候是要在二者之间找平衡点

    1. 读未提交(read uncommitted)

    一个事务还没提交时,它做的变更就能被别的事务看到

    2. 读提交(read committed)

    一个事务提交时,它做的变更才能被其他事务看到

    3. 可重复读(repeatable read)

    一个事务执行过程中看到的数据,总是和这个事务在启动时看到的数据是一致的。当然在可重复读的隔离级别下,未提交变更对其他事务也是不可见的

    4. 串行化(serializable)

    对于同一行记录,写会加写锁,读会加读锁。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成才能继续执行

    总结

    1. 在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在可重复读隔离级别下,这个视图是在事务启动的时候创建的,在整个事务期间都在用这个视图。读提交隔离级别下,这个视图在每个SQL语句执行时创建的。读未提交直接返回记录上的最新值,没有视图的概念。串行化直接用加锁的方式来避免并行访问

    2. Oracle数据库的默认隔离级别是读提交,因此一些从Oracle迁移到MySQL的应用,为了保证数据库隔离级别的一致性,要讲MySQL的隔离级别设置为读提交

    3. MySQL的默认隔离级别是可重复读,可以用select @@global.tx_isolation;查看

    4. 四种隔离级别和三种问题

  • 相关阅读:
    signal(SIGCHLD, SIG_IGN)和signal(SIGPIPE, SIG_IGN);
    关于pthread_cond_wait使用while循环判断的理解
    linux的sleep()和usleep()的使用和区别
    C中结构体的存储分配
    扯扯python的多线程的同步锁 Lock RLock Semaphore Event Condition
    线程属性的初始化以及销毁
    Mysql数据库一个表字段中存了id,并以逗号分隔,id对应的详细信息在另一个表中
    sqlyog 注册码
    Oracle 12C卸载图文教程
    Oracle12c Release1安装图解(详解)
  • 原文地址:https://www.cnblogs.com/swifthao/p/13269758.html
Copyright © 2011-2022 走看看