zoukankan      html  css  js  c++  java
  • 并发事务和隔离级别

    事务的ACID特性

    原子性(Atomicity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用。
    一致性(Consistency): 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的。
    隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。
    持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

    并发事务的问题

    • 丢失修改(Lost to modify): 事务A、B同时访问数据,A修改了这个数据后,B也修改了,则A的修改结果就丢失了。
    • 脏读(Dirty read): 事务A对数据进行了修改,修改没有提交时,事务B读取这个未提交的“脏数据”。
    • 不可重复读(Unrepeatableread): 事务A内两次读同一数据期间,事务B修改了该数据,则A内两次读到的数据不一样。
    • 幻读(Phantom read): 事务A读取数据期期间,事务B插入或删除了几行记录。在随后的查询中,A发现记录多了火烧了,就好像发生了幻觉一样,所以称为幻读。

    不可重复读和幻读区别:
    出现不一致的细粒度不同,不可重复读是A第二次读一条记录发现某些列的值被修改,幻读的重点在于A发现增多或减少几行记录

    隔离级别

    在数据库事务中,为保证并发数据读写的正确性而提出的定义,它并不是MySQL专有的概念,而是源于ANSI/ISO制定的SQL-92标准。

    每种关系型数据库都提供了各自特色的隔离级别实现,以最常见的MySQL InnoDB引擎为例,它是基于MVCC(Multi-Versioning Concurrency Control)和锁的复合实现,按照隔离程度从低到高,MySQL事务隔离级别分为四个不同层次:

    • 读未提交(Read uncommitted):一个事务能够看到其他事务尚未提交的修改,是最低的隔离水平,可能出现脏读、幻读或不可重复读。。
    • 读已提交(Read committed):保证不会看到未提交前的中间性状态,不保证再次读取时能够获取同样的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
    • 可重复读(Repeatable reads):保证同一个事务 对同一字段的多次读取结果是一致的,是MySQL InnoDB引擎的默认隔离级别,可以阻止脏读和不可重复读,但幻读仍有可能发生
    • 串行化(Serializable),所有的事务依次逐个执行,是最高的隔离级别,完全服从ACID,可以防止脏读、不可重复读以及幻读。意味着读要获取共享读锁,更新要获取排他写锁,如果SQL使用WHERE语句,还会获取区间锁 (MySQL以GAP锁形式实现,可重复读级别中默认也会使用,所以MySQ的默认隔离级别也可以防止幻读)。

    悲观锁和乐观锁

    悲观锁一般利用类似SELECT … FOR UPDATE这样的语句对数据加锁,避免其他事务修改数据。乐观锁则与Java并发包中的AtomicFieldUpdater类似,也是利用CAS机制,并不会对数据加锁,而是通过对比数据的时间戳或者版本号,来实现乐观锁需要的版本判断。 MVCC本质就可以看作乐观锁机制,而排他性的读写锁、双阶段锁等则是悲观锁的实现。

    参考

    《Java核心技术36讲》
    《MySQL必知必会》

  • 相关阅读:
    POJ 3126 Prime Path
    POJ 2429 GCD & LCM Inverse
    POJ 2395 Out of Hay
    【Codeforces 105D】 Bag of mice
    【POJ 3071】 Football
    【POJ 2096】 Collecting Bugs
    【CQOI 2009】 余数之和
    【Codeforces 258E】 Devu and Flowers
    【SDOI 2010】 古代猪文
    【BZOJ 2982】 combination
  • 原文地址:https://www.cnblogs.com/ChengzhiYang/p/12512576.html
Copyright © 2011-2022 走看看