首页 > 数据库 >[MySQL事务一文搞懂]

[MySQL事务一文搞懂]

时间:2023-05-17 16:00:32浏览次数:29  
标签:状态 事务 一文 数据库 提交 MySQL 搞懂 执行 隔离

[MySQL事务一文搞懂]

1、什么是事务?

事务(Transaction),顾名思义就是要做的或所做的事情,数据库事务指的则是作为单个逻辑工作单元执行的一系列操作(SQL语句)。这些操作要么全部执行,要么全部不执行。

2、为什么需要事务

把一系列sql放入一个事务中有两个目的:
  • 为数据库操作提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
  • 当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。
    """
    当一个事务被提交给了DBMS(数据库管理系统),则DBMS需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要被回滚,回到事务执行前的状态(要么全执行,要么全都不执行);同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行。
    
    但在现实情况下,失败的风险很高。在一个数据库事务的执行过程中,有可能会遇上事务操作失败、数据库系统/操作系统失败,甚至是存储介质失败等情况。这便需要DBMS对一个执行失败的事务执行恢复操作,将其数据库状态恢复到一致状态(数据的一致性得到保证的状态)。为了实现将数据库状态恢复到一致状态的功能,DBMS通常需要维护事务日志以追踪事务中所有影响数据库数据的操作。
    """
    

3、事务的四大特性(ACID)

ACID 即Atomicity、Consistency、Isolation、Durability的缩写

1、原子性(Atomicity)
一个事务的执行是整体性的,不可分割,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
2、一致性(Consistency)
事务应确保数据库的状态从一个一致状态转变为另一个一致状态。例如转账行为中:一个人减了50元,另 外一个人就应该加上这50元,而不能 是40元。其他一致状态的含义是数据库中的数据应满足完整性约束, 例如字段约束不能为负数,事务执行完毕后的该字段也同样不是负数
3、隔离性(Isolation)
多个事务并发执行时,一个事务的执行不应影响其他事务的执行, 且多个事务不能看到对方的中间状态(提交或者回滚之前的状态)
4、持久性(Durability)
一个事务的提交,对数据库的修改是永久保存在数据库中的,不受外部因素或其他操作影响。

4、事务的隔离级别

注意:  下方表格即代表 每个隔离级别是否存在并发事务所导致的问题!

隔离级别 脏读 不可重复读 幻读
Read uncommitted 读未提交
Read committed 读已提交 ×
Repeatable Read (MySQL默认隔离级别) 可重复读 × ×
Serializable 串行化 × × ×

5、并发事务导致的问题!

注意:下列问题其实就是由于并发事务可能会出现的问题(可用提高数据库隔离级别解决 下面会详解)
  1. 脏读(dirty read)

    """
    脏读其实就是 事务A 读取到了 事务B 未提交的数据!
    
    比如:
    	事务A 查询账户金额为200
    	在此期间 事务B 将当前账户存入100 但是并未提交事务(事务只有再提交后才生效)
    	接下来 事务A 又查询了当前账户金额 发现为300!
    	事务B 并未提交数据 而 事务A 则读取到事务B未提交后的数据!
    	
    解决:
    	将数据库隔离级别修改为: Read committed
    """
    
  2. 不可重复读(non repeatable read)

    """
    不可重复读其实就是 事务A 执行相同的Sql却读取到了不同的数据!
    (和脏读不同的是 它读取到的是已经提交过的事务数据)
    
    比如:
    	事务A 查询账户金额为 200
        事务B 修改金额为300 并且提交事务
        然后 事务A 又查询了账户金额发现为 300 
        这样就导致了 事务A 再同一次事务中执行同样的Sql而获取到不同的值!
    
    解决:
    	将数据库隔离级别修改为: Repeatable Read
    """
    
  3. 幻读(phantom read)

    """
    幻读其实就是事务A再查询某条数据发现并不存在!但是再插入数据的时候却发生ERROR说当前数据已经存在
    (其实这是再不可重复读解决后发生的下一个问题)
    
    比如:
    	事务A 查询 ID=3 的数据没有!
    	此时 事务B 启动 执行插入了 id=3的一条数据
    	然后 事务A 发现ID为3的数据 并没有 也插入了一条 id=3的数据后报错说 已经存在!
    	这是因为 我们的数据隔离级别已经是可重复的 所以事务A 每次查询到的都是最初未改变的状态!
    
    解决:
    	将数据库隔离级别修改为: Serializable
    	
    """
    

标签:状态,事务,一文,数据库,提交,MySQL,搞懂,执行,隔离
From: https://www.cnblogs.com/liupengfei1123/p/17409034.html

相关文章

  • MySQL回表 索引覆盖02
    资料来源:  https://zhuanlan.zhihu.com/p/401198674?utm_id=0  ......
  • mysql 调优-利用索引覆盖和下推
    回表只查询一次索引得不到想要的数据,典型的场景就是非聚簇索引查询:先拿到主键ID,再根据id查询一次得到数据(再次查询这就是回表)索引覆盖:根据普通索引查询不回表就能得到数据--联合索引(age,addr)selectage,addrfromt_userwhereage>10;--单列索引(不一定非要联合索引......
  • mysql 事务与隔离级别
    ACIDAtomicity:原子性(UNDOLOG实现),一组操作要么都成功,要么都失败Consistency:一致性(UNDOLOG实现),从一个合法状态变为另一个合法状态(语义上不是语法上)。比如转账之后余额为负数,虽然也能守恒,但是明显不合法。或者转账时A账户钱少了,B账户钱没多,也是不合法的Isolation:隔离性(锁机制实......
  • mysql 锁机制
    表锁:InnoDB支持行锁,不代表着就不支持表锁表锁的S和X锁,MyISAM的锁(不建议在InnoDB中使用)--查看当前有表锁的表showopentableswherein_use>0;--给表加S锁(所有事务都能读,所有事务都不能写)locktablestable_nameread;--给表加X锁(拿到锁的事务可写可读......
  • mysql 底层数据存储结构
    内存和磁盘每次交互都是完整的页,数据页里面存放的是行(不仅仅是数据库的数据行,还有行格式等)页(16k,计算机与内存的最小单位)的上层单位还有区(一个区存放64个页,64*16k=1024k,刚好1M),区上面是段(一个或多个区组成),段上面是表空间(一个或多个段组成)行格式showtablestatuslike't_u......
  • docker 部署nacos单机版并配置mysql支持
    1.配置mysql数据库选用mysql5.7表名为nacos_config,附上建表SQLSETNAMESutf8mb4;SETFOREIGN_KEY_CHECKS=0;--------------------------------Tablestructureforconfig_info------------------------------DROPTABLEIFEXISTS`config_info`;CREATETABLE......
  • springboot中使用application.properties配置mysql和sqlserver
    1.使用依赖*mysql:<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>*sqlserver:<dependency><groupId>com.microsoft.sqlserver</groupId><art......
  • mysql 存储引擎和索引
    存储引擎引擎特性文件InnoDB默认,支持事务,支持外键,支持行锁和表锁.frm文件存储表结构.ibd文件存储数据和索引MyISAM不支持事务,不支持外键,只支持表锁不支持行锁专门维护了一个常量保存每个表的总记录数(count很快)MyISAM强调的是性能,所以性能上优于InnoDB,但安全......
  • 玩转MYSQL数据库之--视图详解
    前言从今天开始本系列文章就带各位小伙伴学习数据库技术。数据库技术是Java开发中必不可少的一部分知识内容。也是非常重要的技术。本系列教程由浅入深, 全面讲解数据库体系。 非常适合零基础的小伙伴来学习。全文大约【1297】字,不说废话,只讲可以让你学到技术、明白原理的纯......
  • 关于使用Serilog配置MySql数据库和appsettings的问题
    1、项目使用dtonet6WebApi。2、Nuget包:用来访问mysql数据库Pomelo.EntityFrameworkCore.MySqlSerilog日志Serilog配合dotnetSerilog.AspNetCore读取环境变量配置Serilog.Settings.ConfigurationSerilog读取MySqlSerilog.Sinks.MySQL输出到控制台中Serilog.Sinks.Co......