[MySQL]事务的浅谈

        欲买桂花同载酒 终不似 少年游        

目录

 1.MySQL为什么需要事务

2.MySQL对事务的支持

3.关于事务的操作

控制方式(对于单条SQL)

控制方式二(START TRANSACTION 或 BEGIN)

4.关于ACID

 5.关于事务的隔离级别

5.1事务可能存在的问题

5.2事务隔离级别

5.3难点(RR 级别 和 幻读问题) [仅供参考]

6.事务的实现原理

实现事务功能的三个技术如下:

实现事务采取了哪些技术以及思想?


 1.MySQL为什么需要事务

MySQL 支持事务的原因是,事务提供了一种机制,可以确保在多个操作之间维护数据的一致性和完整性。当多个用户同时访问数据库时,如果没有事务机制,可能会出现以下问题:

  • 数据丢失:如果两个用户同时修改同一条记录,最后一个提交的修改会覆盖掉之前的修改,导致数据丢失。

  • 数据不一致:如果多个操作需要修改多条记录,但是其中一条记录修改失败,那么其他记录的修改也将无法提交,导致数据不一致。

  • 并发访问问题:如果多个用户同时访问同一条记录,可能会出现读取过期数据或者写入数据冲突的情况,导致数据不正确。

通过使用事务机制,可以解决上述问题,确保多个操作之间的一致性和完整性。事务可以将多个操作视为一个整体,要么全部成功,要么全部失败,从而确保数据的正确性。

在 MySQL 中,事务是通过 ACID 原则来实现的.

因此,事务机制是数据库管理系统中非常重要的一部分,它可以确保数据库的数据完整性、一致性和可靠性。当多个用户同时对数据库进行操作时,事务机制可以保证每个操作都是独立的,并且不会相互干扰,从而保证数据的正确性。

2.MySQL对事务的支持

show engines;  //查看不同存储引擎的特性

[MySQL]事务的浅谈_第1张图片

可以看到,在 MySQL 中只有使用了 Innodb 数据库引擎才支持事务,MyISAM不支持。

3.关于事务的操作

控制方式(对于单条SQL)

SET AUTOCOMMIT=0;                    //SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1;                   //SET AUTOCOMMIT=1 开启自动提交
show variables like 'autocommit';    //查看事务的提交方式

[MySQL]事务的浅谈_第2张图片

  •  在mySQL中,事务默认是自动提交的(当然这和你的配置文件有关).
  •  对于InnoDB每一条SQL语言都默认封装成事务,自动提交。(select有特殊情况,因为
  • MySQL有MVCC)
  • 当设置 AUTOCOMMIT 为 0 时,MySQL 将关闭自动提交模式,即所有的 SQL 语句都不会自动提交到数据库中,而是需要显式地使用 COMMIT 命令来提交事务。        如果你忘记提交事务,那么这些 SQL 语句所做的修改将不会被保存到数据库中,从而导致数据的不一致。
  • 特别注意的是  当设置 AUTOCOMMIT 为 1 时,对于事务的控制方式二并不会产生任何影响,只要输入begin或者start transaction,事务便必须要通过commit提交,才会持久化,与是否设置set autocommit无关。

控制方式二(START TRANSACTION 或 BEGIN)

开启事务: START TRANSACTION 或 BEGIN ; 
提交事务: COMMIT; 
回滚事务: ROLLBACK;

更详细的控制语句(https://www.runoob.com/mysql/mysql-transaction.html)

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

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

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

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

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

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

SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

4.关于ACID

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

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


一致性(Consistency):

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


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

        数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)


持久性(Durability):

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

 5.关于事务的隔离级别

5.1事务可能存在的问题

问题 描述
脏读 一个事务读到另一个事务还没提交的数据
不可重复读 一个事务先后读取同一条记录,但两次读取的数据不同
幻读 一个事务按照条件查询数据时,没有对应的数据行,但是再插入数据时,又发现这行数据已经存在

5.2事务隔离级别

  • 读未提交【Read Uncommitted】: 在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等
  • 读提交【Read Committed】 :该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select, 可能得到不同的结果。
  • 可重复读【Repeatable Read】  MySQL 默认的隔离级别它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是会有幻读问题。MySQL在RR级别的时候,是解决了幻读问题的(解决的方式是用Next-Key锁(GAP+行锁)解决的。
  • 串行化【Serializable】: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁。但是可能会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)
隔离级别 脏读 不可重复读 幻读 加锁读
Read Uncommitted (未提交读) 不加锁
Read Committed (提交读) × 不加锁
Repeatable Read(可重复读,默认方式) × ×

×

不加锁
Serializable (串行化) × × × 加锁
  • √表示在当前隔离级别下该问题会出现
  • Serializable 性能最低;Read uncommitted 性能最高,数据安全性最差

如和设置事务的隔离级别

查看事务隔离级别: SELECT @@TRANSACTION_ISOLATION; 
设置事务隔离级别: SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }; SESSION 是会话级别,表示只针对当前会话有效,GLOBAL 表示对所有会话有效

5.3难点(RR 级别 和 幻读问题) [仅供参考]

这个问题比较复杂,我也做了一些小测试(),结论大概是这样的

mysql是仅第一次select(指快照读)的时候会创建 read view,而后的select就是建立在本会话和第一次select上面的了,所以从定义上是,mysql的是解决了幻读问题的,但是mysql 同时也支持当前读,这问题上面就仁者见仁智者见智了吧...

参考文章:

MySQL RR 与 幻读问题(实验 + 案例)_π大星的日常的博客-CSDN博客

MySQL的RR级别解决幻读问题了吗 - 掘金

6.事务的实现原理

实现事务功能的三个技术如下:

  1. 日志文件(redo log 和 undo log)
  2. MySQL锁技术
  3. 多版本并发控制MVCC(MultiVersion Concurrency Control)
    • 概念: InnoDB的 MVCC ,是通过在每行记录的后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存了行的过期时间,当然存储的并不是实际的时间值,而是系统版本号。
    • 思想: 通过数据多版本来做到读写分离。从而实现不加锁读进而做到读写并行。

实现事务采取了哪些技术以及思想?

  • 原子性:使用 undo log, 从而达到回滚;
  • 持久性:使用 redo log,从而达到故障后恢复;
  • 隔离性:使用锁以及MVCC,运用的优化思想有读写分离,读读并行,读写并行;
  • 一致性:通过 原子性,持久性,隔离性 从而保证了事务的一致性

你可能感兴趣的:(MySQL,mysql,数据库)