【mysql】mysql 事务

 mysql事务 

在数据库中,对数据的一系列操作在逻辑上可以看成一个整体的操作,这个整体的操作就叫事务。 

ACID 属性

  • 原子性(Atomicity)原子性是指事务是一个不可再分割的工作单位,要求每个事物中的所有操作要么全部完成,要么就像全部没有发生一样
  • 一致性(Consistency)是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
  • 隔离性(Isolation)隔离性保证了并发执行多个事物对系统的状态的影响和串行化执行多个事物对系统的状态的影响是一样的,多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果
  • 持久性(Durability)意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。数据库管理系统采用锁机制来实现事务的隔离性

事务所带来的并发问题主要有以下这几点: 

  • 更新丢失

指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改

  1. 第一类丢失更新:回滚丢失,隔离级别可以解决
  2. 第二类丢失更新:覆盖丢失/两次更新问题,只能通过锁解决,乐观锁或悲观锁
  • 脏读

当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是 “脏数据” ,依据 “脏数据” 所做的操作可能是不正确的。

  • 不可重复读

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

  • 幻读

它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

幻读和不可重复读的区别,幻读和不可重读读都是读取了另一个事务中已经提交的数据,不同的是不可重复读多次查询的都是同一个数据项,针对的是对同一行数据进行修改(Update)或删除(Delete),而幻读针对的是一个数据整体(数据的条数),主要是插入(Insert)操作 

对于上面这几点,通用的解决思路是更新丢失通过应用程序完全避免。而其他的问题点则通过调整数据库事务隔离级别来解决。事务的隔离机制的实现手段之一就是利用锁。

事务隔离级别

事务具有隔离性,理论上说事务之间的执行不应该相互影响,其读数据库的影响应该和他们串行时执行一样。 完全的隔离性会导致系统并发性能很低,降低对资源的利用率,因而实际上会对隔离性的要求会有所放松。

SQL 标准为事务定义了四个不同的隔离级别,从低到高依次是:

  • READ-UNCOMMITTED(读取未提交)

    最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

  • READ-COMMITTED(读取已提交)

    允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

  • REPEATABLE-READ(可重复读)

    对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。MySQL中的InnoDB和Falcon存储引擎通过MVCC(Multi-Version Concurrency Control,多版本并发控制)机制解决了该问题,需要注意的是,多版本控制只是解决了不可重复读的问题,而加上间隙锁(也就是它这里所谓的并发控制)才解决了幻读问题

  • SERIALIZABLE(可串行化)

    最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。 (该隔离级别需要加锁实现,因为要使用加锁机制保证同一时间只有一个事务执行,也就是保证事务串行执行。)

隔离级别脏读不可重复读幻读
READ-UNCOMMITTED
READ-COMMITTED×
REPEATABLE-READ××
SERIALIZABLE×××

MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)

这里需要注意的是:与 SQL 标准不同的地方在于 InnoDB 存储引擎在REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key Lock 锁算法(等于记录锁(Record Lock) + 间隙锁(GAP Lock),因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。所以说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要求,即达到了 SQL标准的SERIALIZABLE(可串行化) 隔离级别。

因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取提交内容):,但是你要知道的是InnoDB 存储引擎默认使用 REPEATABLE-READ(可重读)并不会有任何性能损失。

InnoDB 存储引擎在 分布式事务 的情况下一般会用到SERIALIZABLE(可串行化) 隔离级别。

目前数据库管理系统普遍采用 两段锁 TwoPhase Locking 协议(简称 2PL)的的方法实现并发调度的可串行性,从而保证调度的正确性 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值