您现在的位置是:首页 >其他 >MySQL数据库:事务网站首页其他

MySQL数据库:事务

Hey小孩 2023-05-17 16:00:02
简介MySQL数据库:事务

一、事务简介

1.概念

        事务就是一组DML(sql)语句组成的集合,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败,是一个整体。

2.ACID特性

2.1 原子性A

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

2.2 一致性C

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

2.3 隔离性I

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

2.4 持久性D

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

二、事务并发操作带来的问题

1.脏读

        比如事务A进行了数据修改,但还未提交,此时事务B对该数据进行了查询,之后事务B发现问题对事务进行了回滚。

        此时事务B就是脏读,读取到来其他事务还未提交之后的修改结果

2.不可重复读

        一个事务在不同的时间段,读取同一个数据得到了不同的结果(中途其他事务对数据进行了修改提交)。

3.幻读

        同一个事务在不同的时间段,读取到的结果条数不同(中途其他事务对数据进行了修改提交,导致某些数据满足或不满足了该事务读取条件,导致该事务两次读取结果条数不同)。

4. 解决方法

        MySQL数据库针对并发操作存在的问题,提供了四种隔离级别,如下。 

三、事务隔离级别

1. 读未提交

        在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别),但是相当于没有任何隔离性,仍有很多并发问题,如脏读,幻读,不可重复读等。

        不加锁,什么问题都没有解决。

2.读已提交

        该隔离级别是大多数数据库的默认的隔离级别( MySQL 不是)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读, 即一个事务执行时,如果多次 select, 可能得到不同的结果。

        解决了脏读,仍然存在不可重复读和幻读问题。

3.可重复读

        MySQL默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行

        解决了脏读、不可重复读、幻读问题。

4.串行化

        事务的最高隔离级别,它通过加锁强制事务按序、串行化执行,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁。但是可能会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)。

        解决了所有问题。

隔离级别如何实现?

        隔离,基本都是通过锁实现的,不同的隔离级别,锁的使用是不同的。常见有,表锁,行锁,读 锁,写锁,间隙锁(GAP),Next-Key锁(GAP+行锁)等。

四、可重复读解决并发问题思想

1.基于MVCC多版本并发控制

        MySQL数据库的可重复读隔离级别中,基于MVCC多版本并发控制,解决不可重复读幻读的问题。

2.MVCC实现思想

(1)每张表中都有三个隐藏字段

        ①DB_TRX_ID:最近修改事务ID,记录创建/最后一次修改该记录的事务ID。

        ②DB_ROW_ID:隐含的自增ID(隐藏主键),如果数据表没有主键, InnoDB会自动以DB_ROW_ID 产生一 个聚簇索引。

        ③DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本。

(2)MySQL为每个事务生成一个事务ID

        事务ID是持续增长的,即越往后的事务,事务ID越大。

3.解决原理

(1)修改操作的事务,会先将原始数据向undo日志中保存一份,并且给当前数据操作事务ID为自己的事务ID。

(2)查询操作的事务,在查询数据的时候,只能从数据库的undo日志中获取比自己小的事务ID,且已经提交了的数据。

五、事务操作

1.开始事务

begin;

        开始事务。

2.保存事务回滚点

savepoint pos_name;

        保存事务回滚点,并命名为pos_name。

3.提交事务

commit;

        提交事务

4.回滚事务

(1)rollback

        事务全部回滚,即回滚到事务开始前。

(2)rollback to 回滚点

        回滚到指定位置。

注意:

①事务未提交时:随时可以回滚,并且出现异常未完成事务时,数据库重启后也会自动回滚。

②事务提交后:根据事务的持久性,数据将被持久化存储,无法再回滚。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。