MySQL 事务详解

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱、文章等等,这样,这些众多的数据库操作语句就构成一个事务!

  • 在 MySQL 中只有使用了 InnoDB 数据库引擎的数据库或表才支持事务。

  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

  • 事务用来管理 insert、update、delete 语句。

一般来说,事务必须满足以下 4 个条件(ACID)

  • 原子性Atomicity,或称不可分割性):

    一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

  • 一致性Consistency):

    在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

  • 隔离性Isolation,又称独立性):

    数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。

  • 持久性Durability):

    事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

而我们在学习事务的时候最复杂也是最重要的就是事务的隔离性问题,使用不同的事务隔离级别,在并发事务中就有可能发生脏读不可重复读幻读这些问题。

并发事务中最典型的 3 个数据不一致的问题:

  1. 脏读(Dirty Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个事务 rollback 了操作,则后一个事务所读取的数据就会是不正确的。若事务隔离级别为读未提交(Read uncommitted),那么就有可能发生脏读问题。

  2. 不可重复读(Nonrepeatable Read):在一个事务的两次查询之中有些数据前后两次不一致,这可能是两次查询过程中间,别的事务更改了这些数据并提交了事务。若事务隔离级别为读已提交(Read committed),那么就有可能发生不可重复读问题。

  3. 幻读(Phantom Read):在一个事务的两次查询之中数据条数(rows)不一致,这可能是两次查询过程中间,别的事务插入了新数据并提交了事务。若事务隔离级别为可重复读(Repeatable read),那么就有可能发生幻读问题。

注:从另一个角度来说,可重复读隔离级别限制了在事务读取期间其他事务不能更改数据,但可以插入数据。

事务的隔离级别和对应可能发生的数据不一致问题:

  1. 读未提交(Read uncommitted):所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。此隔离级别可能会发生脏读不可重复读幻读

  2. 读已提交(Read committed):一个事务只能看见已经提交事务所做的改变 。即一个事务在处理期间可能有其他事务进行 update 并 commit,所以该事务再次 select 可能返回不同结果。这就是不可重复读的意思,当然此隔离级别也可能发生幻读

  3. 可重复读(Repeatable read):不同的事务所做的改变是相互不可见的。但有一个特别的情况,若此时有新的数据 insert(记住不是 update 操作),该事务再次 select 就会查到新插入的数据。这就是幻读的意思。

    InnoDB 和 Falcon 存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

  4. 可串行化(Serializable):这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别下,可能导致大量的超时现象和锁竞争,但不会发生数据不一致的问题。

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作,这种称为隐式事务。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

注1:MySQL 默认的事务隔离级别为 repeatable-read。

注2:Oracle 默认的事务隔离级别为 read-committed。

事务控制的常用语句:

  • BEGIN 或 START TRANSACTION 显式地开启一个事务;

  • COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使得已对数据库进行的所有修改成为永久性的;

  • ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。ROLLBACK 会终止事务,并撤销正在进行的所有未提交的修改;

  • SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;

  • RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

  • ROLLBACK TO identifier 把事务回滚到标记点;

  • SET TRANSACTION 用来设置事务的隔离级别。

事务处理的两种方法:

1、用 BEGIN,ROLLBACK,COMMIT 来实现:

  • BEGIN 开始一个事务

  • ROLLBACK 事务回滚

  • COMMIT 事务确认

2、直接用 SET 来改变 MySQL 的自动提交模式:

  • SET AUTOCOMMIT=0 禁止自动提交

  • SET AUTOCOMMIT=1 开启自动提交

事务相关的查询命令:

  • 查看当前会话的隔离级别:

    select @@tx_isolation;
  • 查看系统当前的隔离级别:

    select @@global.tx_isolation;
  • 设置当前会话的隔离级别:

    set session transaction isolation level repeatable read;
  • 设置系统当前的隔离级别:

    set global transaction isolation level repeatable read;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值