mysql—mysql数据库事务的基本概念以及隔离级别(代码片段)

刘Java 刘Java     2022-12-08     170

关键词:

详细介绍了Mysql数据库事务的基本概念、并发事务的问题、事物的实现原理以及隔离级别。

在数据库中,事务是数据库操作的最小逻辑工作单元,一个事务是由一个或多个完成一组的相关行为的SQL语句组成,通过事务机制确保这一组SQL语句所作的操作要么都成功执行,完成整个工作单元操作,要么一个也不执行(都失败)。

重要的是,一个事务当中的所有操作要么都成功,要么都失败,这样的特性,保证了用户每一个操作的可靠性,即使中途出现异常,也不会破坏原来的数据。比如常见的转帐案例,因为转账操作分为多个步骤,这就要用事务来处理,用以保证数据的一致性。

MySQL的InnoDB 引擎支持事务,而MyISAM则不支持事务。

1 事物的特性

  1. Atomicity:原子性,事务的不可分割的,事务的所有操作要么都成功,要么都失败。
  2. Consistency:一致性,多个客户端进行同时访问的时候,通过事务可以对多个客户端保持数据的一致性。例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
  3. Isolation:事务的隔离性,多个事务并发操作的时候,多个事务之间互相不影响,彼此独立。
  4. Durability: 事务的持久性,数据的改变通过事务的提交可以永久的保存在数据库当中,即使数据库发生故障也不应该对其有任何影响。

2 并发事务的问题

在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一数据进行操作)。并发虽然是必须的,但可能会导致以下的问题。

  1. 更新丢失(Lost Update)
    1. 当多个事务选择同一行操作,并且都是基于最初选定的值,由于每个事务都不知道其他事务的存在,就会发生更新覆盖的问题。类比github提交冲突。
  2. 脏读(Dirty Read)
    1. 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,这就叫脏读。脏读导致一个事务读取了被其他事务修改但还未提交的数据。
    2. 如:事务T1修改了一条数据,但是还未提交,事务T2此时读取到了这条修改后了的数据,如果此时T1将事务回滚,这个时候T2读取到的数据就是脏数据。
  3. 不可重复读(Non-Repeatable Read)
    1. 是指一个事务读取数据库中的数据后,另一个事务则修改或删除数据,当第一个事务再次执行同一查询时,就会发现数据已经发生了改变,这就是不可重复读。不可重复读所导致的结果就是一个事务前后两次读取的数据不相同,可以读取到其他事务更新/删除后的数据。
    2. 即不可重复读发生在一个事务执行两次或两次以上的相同查询时,查询结果不一致。这通常是由于另一个并发事务在两次查询之间修改/删除并提交了符合查询条件的数据。
    3. 如:事务T1按照条件读取一批记录,紧接着事务T2修改并提交了T1刚刚读取的那一批记录,然后T1再一次查询,发现与第一次读取的记录不同。
  4. 幻读(Phantom Read,不一定会发生)
    1. 是指一个事务读取数据库中的数据后,另一个事务则插入了数据数据,当第一个事务再次执行同一查询时,就会发现数据已经发生了改变,多出来了数据,这就是幻读。幻读所导致的结果就是一个事务前后两次读取的数据不相同,可以读取到其他事务新插入的数据。
    2. 即幻读发生在一个事务执行两次或两次以上的相同查询时,查询结果不一致。这通常是由于另一个并发事务在两次查询之间插入并提交了符合查询条件的数据。
    3. 如:事务T1按照条件读取一批记录,紧接着事务T2插入并提交了符合T1查询条件的记录,然后T1再一次查询,发现与第一次读取的记录不同。

3 事务的简单实现原理

  1. MySQL InnoDB 引擎通过undo log回滚日志来保证原子性。
  2. MySQL InnoDB 引擎使用 redo log重做日志 保证事务的持久性。
  3. MySQL InnoDB 引擎通过锁机制、MVCC 等手段来保证事务的隔离性( 默认支持的隔离级别是 REPEATABLE-READ )。
  4. 保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。

关于这几种日志,我们在之前的文章中已经讲过了。

4 事务的隔离级别

数据库允许多个事务的并行,事物的隔离级别就用来表示此事务与其他并行事务的工作隔离的程度。例如,此事务能否看到来自其他事务的未提交的写入?不同的数据库有不同的默认事务隔离级别。由于并行事务,不同的隔离级别可能会带来不同的数据访问现象/安全问题。换句话说,事务的隔离级别是根据是否会出现上面讲的的某些现象来区分的!

在SQL92标准中,针对大部分数据库定义了4个标准的事务隔离级别:

  1. 读未提交(Read Uncommitted):就是一个事务可以并发的读取另一个未提交事务变更的数据。存在脏读、不可重复读、幻读的问题。
  2. 读已提交(Read Committed):一个事务可以并发的读取另一个事务提交后的数据。解决了脏读问题,还有不可重复读和幻读的问题。Sql Server , Oracle的默认隔离级别。
  3. 可重复读(Repeatable Read):一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。即事务在执行期间看到的数据前后必须是一致的。可能出现幻读。MySQL的默认隔离级别就是Repeatable Read。
    1. 实际上,mysql在默认的可重复读隔离级别下,mvcc的普通的查询是快照读,提供了一致性视图,不会看到别的事务插入的数据的,也就不存在所谓的“幻读”了,而如果使用当前读,那么则会加上行锁+Gap间隙锁,其他事务的插入操作则根本无法进行,因此实际上mysql的InnoDB引擎已经使用mvcc解决了幻读的问题(见《高性能MySQL》)。那么这里的幻读是什么呢?这里更多是指的oracle的操作,所以你用mysql测试的话,幻读很有可能测不出来。
    2. 当前读:select…lock in share mode (共享读锁)、select…for update、update语句、delete语句、insert语句
  4. 序列化/串行化(Serializable):Serializable 是最高的事务隔离级别,在该级别下,事务通过加锁的方式直接避免并行访问,可以避免脏读、不可重复读与幻读问题,严重影响程序性能。读的时候加共享锁,也就是其他事务可以并发读,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读。

Oracle默认的隔离级别是read committed,还支持SERIALIZABLE。MySQL默认隔离级别: Repeatable Read,并支持全部四种级别。

可以用show variables like 'transaction_isolation';命令来查看当前的隔离级别:
在这里插入图片描述

在不同的隔离级别下,数据库行为是有所不同的。事务的隔离级别设置越高,异常就出现的越少,但并发效果就越低,事务的隔离级别设置越小,异常出现的越多,并发效果越高。

下一篇文章中,我们将介绍MySQL数据库事务的不同隔离级别的实现原理以及MVCC。

参考资料:

  1. 《 MySQL 技术内幕: InnoDB 存储引擎》
  2. 《高性能 MySQL》
  3. 《MySQL实战45讲 | 极客时间 | 丁奇》

如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!

mysql中事务四大特性的实现详解

...修改必须和其余的事务隔离持久性Duration:事务完成后,对数据库中数据的修改会持久化存储事务的四种隔离级别:隔离级别脏读不可重复读幻读未提交读ReadUncommitted可能可能可能已提交读ReadCommitted不可能可能可能可重复读RepeatableRe... 查看详情

mysql中事务四大特性的实现详解

...修改必须和其余的事务隔离持久性Duration:事务完成后,对数据库中数据的修改会持久化存储事务的四种隔离级别:隔离级别脏读不可重复读幻读未提交读ReadUncommitted可能可能可能已提交读ReadCommitted不可能可能可能可重复读RepeatableRe... 查看详情

mysql索引事务及存储引擎(代码片段)

...到该行数据对应的物理地址来访问对应的数据,加快数据库的查询速度索引相当于一本书的目录,通过目录快速找到所需要的内容索引是表中一列或者若干列值排序的方法建立索引的目的是加快对表中记录的查找或排序... 查看详情

mysql中事务以及事务隔离级别的详解(代码片段)

...分享一下给大家,👉点击跳转到网站一、MySQL中事务的理解二、演示事务的基本使用DROPTABLEt27;--1.创建一张测试表CREATETABLEt27(idINT,`name`VARCHAR(32));--2.开启事务STARTTRA 查看详情

mysql事务的隔离级别

事务的隔离级别当数据库里有多个事务同时执行的时候,就可能会出现,幻读,脏读,不可重复读的问题,为了解决这些问题,就出现了隔离级别的概念。读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到。读已... 查看详情

mysql从青铜到王者第八篇:mysql视图事务索引

...2.视图的基本使用1.创建视图2.案例3.视图规则和限制二、事务1.事务基本操作1.创建测试表2.开始一个事务3.提交事务4.回滚事务2.事务操作注意事项3.事务的隔离级别1.无隔离性存在的问题2.事务的隔离级别1.设置事务的隔离级别2.查... 查看详情

第36讲谈谈mysql支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景

在日常开发中,尤其是业务开发,少不了利用Java对数据库进行基本的增删改查等数据操作,这也是Java工程师的必备技能之一。做好数据操作,不仅仅需要对Java语言相关框架的掌握,更需要对各种数据库自身体系结构的理解。今... 查看详情

mysql的事务四个特性以及事务的四个隔离级别(代码片段)

...失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。2、一致性(Consistency)一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执... 查看详情

mysql的事务四个特性以及事务的四个隔离级别(代码片段)

...失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。2、一致性(Consistency)一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执... 查看详情

java--每日一问:谈谈mysql支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?

...型回答所谓隔离级别(IsolationLevel),就是在数据库事务中,为保证并发数据读写的正确性而提出的定义,它并不是MySQL专有的概念,而是源于ANSI/ISO制定的SQL-92标准。每种关系型数据库都提供了各自特色的... 查看详情

mysql数据库中默认事务隔离级别是?

MySQL数据库中默认事务隔离级别是?事务的基本要素(ACID)  1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的... 查看详情

mysql事务隔离级别(代码片段)

...别可以通过MySQL的视图来实现。读未提交读未提交是一个事务仅修改了数据但还未提交时,本次修改可以便可被其他事务查询到变更后的值。读未提交隔离级别下,其他事务进行查询时,直接返回记录上的最新值,... 查看详情

mysql的事务和引擎,注意细品(代码片段)

mysql事务和引擎一、MySQL事务(一)、MySQL事务的概念(二)、事务的ACID特点1、ACID特点2、数据不一致产生的结果:(三)、事务的隔离1、MySQL事物隔离级别1.1查询全局事务隔离级别1.2查询会话事务隔离级别1.3设... 查看详情

第31讲:mysql事务的并发问题以及事务的隔离级别

文章目录1.事务的并发问题1.1.事务并发之脏读1.2.事务并发之不可重复读1.3.事务并发之幻读2.事务的隔离级别3.模拟事务并发问题的产生以及如何避免3.1.事务并发问题脏读的模拟以及避免3.1.1.模拟事务并发脏读的问题3.1.2.解决事... 查看详情

mysql事务基本概念(代码片段)

数据库事务:数据库事务通常指对数据库进行读或写的一个操作序列。系统中的事务:处理一系列业务处理的执行逻辑单元,该单元里的一系列类操作要不全部成功要不全部失败它的存在包含有以下两个目的:1、为数据库操作提供... 查看详情

mysql-09-笔记(代码片段)

事务事务TRANSACTION1.事务的概念2.事务的数据准备3.未管理事务演示4.管理事务演示5.事务的提交方式6.事务的四大特征(ACID)7.事务的隔离级别8.事务隔离级别演示9.隔离级别总结10.事务的总结事务TRANSACTION1.事务的概念一条或多条SQL语... 查看详情

spring事务专题事务的基本概念,mysql事务处理原理

...该慢慢行成一个体系,为了建立一个完善的体系应该要对数据库本身事务的实现有一定认知才行。本文为Spring事务专题第三篇,在前两篇 查看详情

mysql事物隔离级别及搜索引擎(代码片段)

...事物隔离级别及搜索引擎一.MySQL事物隔离级别1.1查询全局事务隔离级别1.2查询会话事务隔离级别1.3设置全局事务隔离级别1.4设置会话事务隔离级别二.事务控制语句三.MySQL存储引擎3.1存储引擎概念介绍3.2MySQL常用的存储引擎:3.3lnnoD... 查看详情