MySQL原理(五)数据库中的事务

本文详细介绍了计算机术语中的事务概念,包括ACID特性,以及MySQL如何通过InnoDB的redolog和undolog日志、MVCC技术来保证事务的原子性、一致性、隔离性和持久性。还讨论了并发事务中可能遇到的问题,如脏读、不可重复读和幻读,以及MySQL的四种隔离级别及其实现方式。
摘要由CSDN通过智能技术生成

一、事务介绍:

1、介绍:

在计算机术语中,事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务是恢复和并发控制的基本单位。

2、事务的4大特性

原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。

2.1、原子性(Atomicity):

事务是一个原子操作,它要么全部成功,要么全部失败回滚。如果事务中的任何操作失败,则所有操作都将回滚到之前的状态,以确保数据库中的数据不会被部分更改。

2.2、一致性(Consistency):

事务的执行必须使数据库从一个一致状态转换到另一个一致状态。这意味着事务必须满足所有约束条件,以保持数据的完整性和一致性。

2.3、隔离性(Isolation):

并发事务的执行不能相互干扰。事务必须在独立的空间内执行,这意味着它们看起来像是在独占访问数据库。

2.4、持久性(Durability):

一旦事务完成提交,其结果就是永久性的,并且即使在系统故障的情况下,也必须能够恢复这些结果。

注意,在firebird中,开启事务的方式是让调用程序使用StartTransaction(开启事务)、COMMIT(提交事务)和ROLLBACK(撤销事务)。

3、mysql保障事务四大特性

3.1、原子性、一致性、持久化

实际上是由InnoDB中的两份日志来保证的,一份是redo log日志,一份是undo log日志。

(1)redo log:重做日志,负责记录的是事务提交时数据页的物理修改,即哪一页哪一行哪个字段做了什么修改。当数据库发生故障时,redo log可以用来恢复未完成的事务,实现事务的持久性。分为重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。

(2)undo log回滚日志,主要作用是在事务进行修改操作但还未提交之前,先记录下原始的数据状态。这样,当事务因为某些原因需要回滚或数据库发生故障时,可以利用undo log中的信息将数据恢复到事务开始前的状态。 作用包含两个 : 提供回滚(保证事务的原子性) 和MVCC(多版本并发控制) 。

(3)MVCC :全称 Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。

注:隐式字段:我们创建表(id,name,age)后,插入数据时,InnoDB还会自动的给我们添加三个隐藏字段,前两个字段是肯定会添加的, 是否添加最后一个字段DB_ROW_ID,得看当前表有没有主键,如果有主键,则不会添加该隐藏字段。

3.2、持久性:

是通过数据库的锁,加上MVCC来保证的。

4、数据库并发事务遇到问题:

(1)赃读:一个事务读到另外一个事务还没有提交的数据。

(2)不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。

(3)幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了 "幻影"。

二、mysql事务隔离级别

1、四种隔离级别

 为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。主要有以下几种,其中(Serializable安全性最高,Uncommitted安全性最差),默认可重复读。

1.1、 read uncommitted (未提交读)

 在read uncommitted 级别中,当在事务A中对数据的修改即使是在事务未提交的时候,其他并发操作的事务依然可以读取到事务A修改的数据,这种情况我们叫做数据“脏读”。那如果事务A在后面出现回滚的操作时,而其他事务在已经读取到的是事务A之前的修改,就会导致出现数据的修改混乱。

1.2、 read committed (已提交读)

在read committed级别中,当一个事务A从开始直到事务提交之前,其他的并发事务对该事务的修改都是不可见的。但是在其他同一事务内执行两次一样的查询时,查询的结果也会不同,所以这个级别同时也叫做不可重复读。

在此隔离级别下,一个事务只能看到其他事务已提交的更改。这意味着,同一个事务中的多次查询可能会看到不同的数据,因为其他事务在此期间可能已经提交了更改。

其他大多数的数据库默认的隔离级别都是read committed ,但是mysql 默认隔离级别不是。

1.3、 repeatable read (可重复读)

repeatable read级别是mysql 默认的事务隔离级别。该级别确保了在一个事务中多次读取结果是一致的,但同时也出现另一个“幻读”的问题。  “幻读”是指当某个事务在读取某个范围内的记录时另一个事务又在该范围内插入了新的数据,那么再次读取该范围的数据时会出现幻行。 MySQL在存储引擎(InnoDB和XtraDB)下是通过锁机制加MVCC(多版本并发控制)来解决幻读的问题。

在此隔离级别下,一个事务启动时看到的数据是一致的。即使其他事务提交了更改,这些更改对当前事务也不可见,确保事务内的多次查询结果一致。

 是MySQL 中默认使用的事务隔离级别,同时需要使用事务时一般使用InnoDB存储引擎。

1.4、 serializable (可串行化)

 serializable隔离级别是将各个事务强制串行执行,在每个事务执行时都会对该事务影响的数据行进行加锁,因此其他并发的事务则无法进行读写操作,需等这条事务提交后并释放锁才能进行下一个事务的执行。由于需要对每条数据都加锁,这样就会导致大量的操作超时和锁争用的问题。在我们的实际项目开发中很少使用这个级别。

之所以默认下第三个,是因为事务隔离级别越高,数据越安全,但是性能越低。

(1)查看事务隔离级别

SELECT @@TRANSACTION_ISOLATION;

(2)设置事务隔离级别

SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } 

2、实现
2.1、MVCC

读提交和可重复读就是依赖于多版本并发控制(MVCC)技术实现的,即为每个事务提供一个数据的一致性快照,

(1)读提交:InnoDB 为每次查询创建一个新的数据快照,该快照包含了在查询开始之前已提交的所有事务所做的更改。

(2)可重复读:InnoDB 为整个事务创建一个数据快照,该快照在事务开始时创建,并在事务执行过程中保持不变。因此,事务内的所有查询都是基于同一快照的。

2.2、锁定策略

(1)读提交:InnoDB 仅在需要修改数据时使用行锁(row lock)对数据进行锁定。对于读操作,不会加锁。并发性能较好,这使得读提交成为许多 OLTP(在线事务处理)系统的首选隔离级别。

(2)可重复读:InnoDB 在读操作中使用一种称为 Next-Key Locking 的锁定策略。这种策略结合了行锁和间隙锁(gap lock),锁定被查询到的行以及这些行之间的间隙。这有助于避免幻读问题。由于在读操作中使用了 Next-Key Locking,可能会导致锁的竞争,从而降低并发性能。然而,可重复读可以在一定程度上解决幻读问题。

注意:可重复读在某些情况下(如查询使用非唯一索引的列时),仍然可能出现幻读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值