关于mysql事务,你还没搞清楚吗

一、ACID

 一个模块,是多个独立的功能逻辑的组合,每个功能包含多个操作步骤,包括IO、计算、数据库等操作,必须保证每一步都被执行,且执行正确,这个功能和模块才是可用,可交付的。

 那么,如何保证这些操作的完整性,就是Atomic,定义为一个原子操作,全部执行且成功,或者全部失败都不执行(回滚),原子操作如果成功,那状态就必须持久,被称为数据库的Durability,持久性。

  • 原子性A、持久性D,这俩个都比较好理解,定义了事务的边界,行为的开始和行为的结束
  • 一致性C、隔离性I,就是对事务中间状态的管理。一致性,也可以理解为是数据的完整性,数据的有效性,我们举例来说明什么是一致性,以及事务是如何保证一致性的,

 一个账户减100,另一个账户加100的时候,程序异常crash了,这时候就出现数据的不一致情况,破坏了有效性,这个问题可以由Atomic来保证;

 一个原子操作在执行的过程中,涉及多个数据变更的中间状态的保护,例如把A账户减100,在加到B账户完成这个原子操作之前,此时,其他线程对A读的操作就有可能获取到A少100的这个中间状态,这种情况是否允许发生,由Isolation来保证;

 数据库延迟约束,例如数据字段的类型、空值、关系、数据范围、主键唯一性等这些合法性的检查都是由Durability来保证,在事务commit时,发现数据不合法,是无法提交成功的。

 所以,综上所述,一致性C,是数据状态的正确变换的保证,AID,是实现C的手段,也是我们真正要追求的目标。

 而,隔离性I的设定,就是对一致性C不同程度的破坏,事实上,如果我们顺序对数据进行读写,ACD是完全可用保证的,但这样效率会非常的低下,那,我们是要严格的一致性,还是更高的效率,数据库专家们把这个决定权交给了用户,所以,我们看到,ACID当中,只有隔离性I是用户可以选择的,可以自定义的。

隔离性包括 串行读、读已提交、重复读、读未提交 等几种策略,性能由低到高,让用户在不同的使用场景,选择合适的隔离策略,在一致性和性能之间平衡,取得最好的综合表现。

二、ACID小结

 总的来说,ACID的核心是C,大家其实都是为得到C而提出的不同纬度的限制和规范,A确定一个功能的完整性,D对状态负责,I可以说是C的等级系数,不同的I的策略,会出现不同的级别的C,AID是数据库本身的功能特性,C由业务层把控,要严格的C,就设置完整的数据库约束和串行隔离,反之,要宽松的C,就放开数据库的约束,使用读未提交的隔离策略,存在即合理,后者更适用于互联网高并发对一致性要求不高的场景,例如分布式的AP系统,可以保证服务整体的响应时间和服务的可用性。

三、隔离介绍

  • 在SQL标准中定义了四种隔离级别, 每一种级别都规定了一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的
  • 较低级别的隔离通常可以执行更高的并发, 系统的开销也更低

四、隔离的级别

  • MySQL能够识别所有的4个ANSI隔离级别,InnoDB引擎也支持所有的隔离级别

READ UNCOMMITTED(未提交读)与脏读

  • 在READ UNCOMMITTED级别,事务中的修改,即使没有提交,对其他事务也都是可见的
  • 事务可以读取未提交的数据,这也被称为脏读(Dirty Read)
  • 这个级别会导致很多问题,从性能上来 说,READ UNCOMMITTED不会比其他的级别好太多,但却缺乏其他级 别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少使用

READ COMMITTED(提交读)与不可重复读

  • 大多数数据库系统的默认隔离级别都是READ COMMITTED(但MySQL不是)
  • READ COMMITTED满足前面提到的隔离性的简单定义:一个事务开始时,只能“看见”已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的
  • 这个级别有时候也叫做不可重复读 (nonrepeatable read),因为两次执行同样的查询,可能会得到不一样的结果

REPEATABLE READ(可重复读)与幻读

  • REPEATABLE READ解决了脏读的问题。该级别保证了在同一个事务中多次读取同样记录的结果是一致的
  • 但是理论上,可重复读隔离级别还是无法解决另外一个幻读(Phantom Read)的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)
  • InnoDB和XtraDB存储引 擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)解决了幻读的问题。本章稍后会做进一步的讨论
  • 可重复读是MySQL的默认事务隔离级别

SERIALIZABLE(可串行化)

  • SERIALIZABLE是最高的隔离级别
  • 它通过强制事务串行执行, 避免了前面说的幻读的问题。简单来说,SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题
  • 实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别

五、隔离的总结

六、MySQL隔离级别的设置

  • MySQL可以使用“SET TRANSACTION ISOLATION LEVEL”命令来设置隔离级别。新的隔离级别会在下一个事务开始的时候生效
  • 设置的两种方式
    ①在配 置文件中设置整个数据库的隔离级别
    ②以只改变当前会话的隔离级别。例如下面在单次会话中设置隔离级别为提交读:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页