Mysql 事务

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013298300/article/details/52403135

Mysql 事务

事务,一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

一、概述

在数据库访问过程中,一系列相关的操作单元我们称之为事务。例如在一个论坛的管理系统中,当我们删除一个用户时,也要删除该用户的邮箱以及相关文章。
下面是SQL语句:
例1

delete from userinfo where XXX
delete from mail where YYY
delete from article where ZZZ

想象一下我们执行的过程中,当delete from userinfo执行成功后,delete from maildelete from article却失败了,这样会出现什么后果?
很多网站都是可以通过邮箱来登录的。那我们如何保证在上面这三句sql语句,即sql单元的原子性?
也就是上面三条sql语句,要么都完成要么都不完成。在mysql中这些问题都由事务解决。

二、事务的特征

事务至少包括原子性、隔离性、一致性、持久性四个特性,即所谓的ACID

  • 原子性
    指的是构成事务的操作语句,也就是操作单元,要么不做,要么全做,绝对不允许出现个别语句执行成功而其它语句执行失败,例如在例1当中不允许第一条语句执行成功而第二第三条执行失败的情况。
  • 隔离性
    指的是多个事务并发执行时,各个事务必须独立执行。在最理想的情况下,
    应象各个事务独立执行一样。但是在事务不是独立时,在事务并发执行时可能出现的问题:
    • 脏读。脏读指的是事务A在执行事务时(事务尚未提交)将i从0变成了1, 此时B事务读取了i = 1,但是事务A提交失败,进行回滚于是i又变成了0。 此时,数据库中i = 0,但是在事务B的逻辑中i = 1,这就是脏读。
    • 不可重复读。假设A事务在执时i = 0,此时B事务读取i = 0,而后
      A事务将执行i = 1,这时B事务再次读取获得i = 1,这样在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。不可重复读产生的原因是事务并发修改数据,最简单的解决方案是对需要修改的数据进行加锁。
    • 幻读。事务A对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行. 同时,B事务也修改这个表中的数据,这种修改是向表中插入一行新数据. 那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
  • 一致性。一致性分为读一致性和写一致性。在数据库系统中,单个数据的操作都是原子的,所以从单个数据的角度上来说,不会出现一致性问题。但是数据库往往关注的是状态,状态由多个数据记录构成。这里的一致性,指的是状态一致性。数据库要么处于状态A,要么出于状态B,而不会处于两者之间。
    • 写一致性。即对状态的写加锁,不允许多个事务并发地对同一个 状态进行更新操作。
    • 读一致性。即对状态的读加锁,当事务A在读取状态时,不允许 有事务并发地对状态进行修改。

二、事务隔离级别

为了应对事务隔离中的脏读、不可重复读,幻读三个问题,我们可以通过直接为所有事务加锁的方法来解决,但是这样实际上就是将所有事务操作进行串行化了,如此一来就无法支持事务的并发执行。因为有时候在某些场景下出现脏读、不可重复读或者幻读对系统没有影响,这种情况下对事务粗鲁地加锁只是白白地浪费性能而已,为了提供灵活性,Mysql的事务机制实现以下几种事务隔离等级供用户在具体情景中选择。

没有更多推荐了,返回首页