首页 > 数据库 >MySQL-事务

MySQL-事务

时间:2024-10-25 19:16:43浏览次数:8  
标签:事务 set 隔离 isolation 提交 MySQL 级别

目录

事务简介

事务操作

事务四大特性ACID

并发事务问题

1.脏读

2.不可重复读

3.幻读

事务隔离级别

1.读未提交Read uncommitted

2.读已提交Read committed

3.可重复读Repeatable Read(默认)

4.串行化Serializable

隔离级别与一致性的关系


事务简介

事务是一组操作的集合,它是一个不可分割的工作单元,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败

一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成

事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同

就比如:用户1需要向用户2转账100元

actno  balance
 1       500
 2       100
进行转账操作:
update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;
  • 以上两台DML语句必须同时成功或者同时失败
  • 最小单元不可再分,当第一条DML语句执行成功后, 并不能将底层数据库中的第一个账户的数据修改,只是将操作记录了一下
  • 这个记录是在内存中完成的,当第二条DML语句执行成功后,和底层数据库文件中的数据完成同步
  • 若第二条DML语句执行失败,则清空所有的历史操作记录,要完成以上的功能必须借助事务

注意:默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交事务

事务操作

1.查看/设置事务提交方式

SELECT @@autocommit ;

SET @@autocommit = 0 ;

2.开启事务

START TRANSACTION 或 BEGIN ;

3.提交事务

COMMIT;

4.回滚事务

ROLLBACK;

案例:

(1)提交操作---无事务成功

update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;

 

(2)提交操作---无事务失败

update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2w;

(3)提交操作---事务成功

start transaction;#手动开启事务
update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;
commit;#commit之后即可改变底层数据库数据

(4)提交操作---事务失败

start transaction;#手动开启事务
update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2w; #这个地方故意让第二个语句出错
commit;#commit之后即可改变底层数据库数据

 

(5)回滚操作---事务失败

start transaction; #开启事务
update act set money = 0 where name = '张三';
update act set money = 200 where name = '李四';
-- 假设这里出现了错误,可以回滚事务
ROLLBACK;
-- 如果没有错误,可以提交事务
COMMIT;

事务四大特性ACID

1.原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败

当事务发现有些语句不能执行时,需要将数据恢复到事务执行前,通过undo log实现

undo log是mysql中比较重要的事务日志之一,顾名思义,undo log是一种用于撤销回退的日志, 在事务没提交之前,MySQL会先记录更新前的数据到 undo log日志文件里面, 当事务回滚时或者数据库崩溃时,可以利用 undo log来进行回退

2.一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态

原子性、持久性和隔离性,都是为了保证数据库状态的一致性

3.隔离性(Isolation):事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰

与原子性、持久性侧重于研究事务本身不同,隔离性研究的是不同事务之间的相互影响

4.持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

持久性问题的产生:

背景:Mysql为了保证存储效率,每次读写文件都是先对缓存池(Buffer Pool)操作, 缓冲池再定期刷新到磁盘中(这一过程称为刷脏)

产生:由于数据不是直接写到磁盘,那么如果主机断电,就会有一部分数据丢失

解决:通过重做日志(redo log)恢复数据。在每次修改数据之前, 都会将相应的语句写到redo log中,如果主机断电,那么再次启动时可通过redo log恢复

拓展:redo log也需要在事务提交时将日志写入磁盘,它比缓冲池写入快的原因有两点:redo log是追加文件写,属于顺序IO,缓冲池是属于随机IO,且刷脏是以页为单位, 有一点修改就要整页写入

并发事务问题

1.脏读

一个事务读到另外一个事务修改但还没有提交的数据

2.不可重复读

一个事务先后读取同一条记录,但两次读取的数据不同

3.幻读

在一个事务中,多次查询同一个范围的数据,却发现有新增或者减少的行。这是因为在这个事务进行的过程中,另一个事务插入或者删除了符合查询条件的数据,导致前后两次查询结果不一致

事务隔离级别

为了解决并发所产生的问题,在数据库中引入了事务的隔离级别,隔离级别越高,数据越安全,但是性能越低,解决并发产生的问题越多

1.读未提交Read uncommitted

  • 事物A和事物B,事物A未提交的数据,事物B可以读取到
  • 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别
  • 三种并发问题都没解决

演示:

MySQL8中隔离级别的变量跟之前的版本不一样,之前是tx_isolation,MySQL8改成了transaction_isolation

#创建表:
create table t_user(id int primary key auto_increment,username varchar(255));

#设置读未提交的隔离级别
set global transaction isolation level read uncommitted;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;

2.读已提交Read committed

  • 事物A和事物B,事物A提交的数据,事物B才能读取到
  • 这种隔离级别高于读未提交
  • 换句话说,只有对方事务提交之后的数据,当前事务才能读取到
  • 这种级别可以避免“脏数据”
  • 这种隔离级别会导致“不可重复读取”
  • Oracle默认隔离级别
#设置读已提交的隔离级别
set global transaction isolation level read committed;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;

插入但没有提交是读不出来的,提交之后才能读出来

不可重复读和脏读的区别:脏读读取到的是一个未提交的数据,而不可重复读读取到的是前一个事务已提交的数据。 而不可重复读在一些情况也并不影响数据的正确性,比如需要多次查询的数据也是要以最后一次查询到的数据为主

3.可重复读Repeatable Read(默认)

  • 事务A和事务B,事务A提交之后的数据,事务B读取不到,事务B是可重复读取数据
  • 这种隔离级别高于读已提交
  • 换句话说,对方提交之后的数据,还是读取不到
  • 这种隔离级别可以避免“不可重复读取”,达到可重复读取,比如1点和2点读到数据是同一个
  • MySQL默认级别
  • 解决了 “不可重复读” 和 “幻读”
#设置可重复读的隔离级别
set global transaction isolation level repeatable read;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;

无论是删除还是添加,commit后都是成功的,但是另一边却还是读出原来的数据,这就是可重复读,读取的是备份数据,不是真正的数据

4.串行化Serializable

  • 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
  • 这种隔离级别很少使用,吞吐量太低,用户体验差
  • 这种级别可以避免“幻读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行, 而不并发
#设置串行化的隔离级别
set global transaction isolation level serializable;
#查看当前隔离级别
select @@global.tx_isolation,@@tx_isolation;

隔离级别与一致性的关系

标签:事务,set,隔离,isolation,提交,MySQL,级别
From: https://blog.csdn.net/m0_73902080/article/details/143213765

相关文章

  • 数据库中对MySQL查询的学习
    MySQL查询目录MySQL查询基本语法条件查询条件查询运算符逻辑运算符排序与分页排序分页弊端与解决方案分组查询单字段分组多字段分组where和having的区别常用函数数值性函数字符串函数日期和时间函数流程控制函数(了解)子查询子查询的基本概念子查询的分类子查询的位置子查询的注意......
  • 初识MySQL · 表的操作
    前言:上一篇文章我们介绍了库的操作,而在我们学习MySQL的第一篇文章就提及了,使用MySQL的时候,先是创建数据库,然后是创建表,表和数据库的重要关系其实是对等的,所以相关的操作,对于增删查改也是同理。删除方面其实对于数据库来说或者是表来说,都是需要非常谨慎的,因为数据库对于开......
  • 高效实现聚水潭·奇门售后单集成到MySQL的关键技术
    聚水潭·奇门数据集成到MySQL:售后单数据的高效对接方案在企业数据管理中,如何实现不同系统之间的数据无缝对接一直是一个关键问题。本文将分享一个具体的技术案例,即如何通过轻易云数据集成平台,将聚水潭·奇门的售后单数据高效集成到MySQL数据库中,形成BI狄菲俪诗-售后表。本次集......
  • 高效集成:聚水潭采购入库数据导入MySQL案例
    聚水潭数据集成到MySQL的技术案例分享在企业数据管理中,如何高效、准确地将业务系统的数据集成到分析平台是一个关键问题。本篇文章将聚焦于一个具体的系统对接集成案例:将聚水潭的采购入库单数据集成到MySQL数据库中,以便在BI勤威平台上进行进一步的数据分析和处理。案例背景本......
  • 关系型数据库(1)----MySQL(初阶)
    目录1.mysql2.mysqld3.mysql架构1.连接层2.核心服务层3.存储引擎层4.数据存储层4.SQL分类5.MySQL操作库6.MySQL数据类型1.数值类型2.日期和时间类型3.字符串类型4.空间类型5.JSON数据类型7.MySQL表的约束1.主键约束(PRIMARYKEY)2.非空约束(NOTNULL)3.......
  • SpringJpa事务和缓存
    背景,一个service,有一个方法serviceA里面调用两个update方法,一个findByName方法。其中serviceA和update方法上都上有@transactional注解,而findByName上没有。示例如下:servcieA{updateByName()updateById()findByName()}先说结论,这个时候具体事务的变化如下:serviceA本身会......
  • mysql之 关联表(left join | right join | inner join | union)
    一.首先给出两张表user表:用户基本信息表score表:分数表(学生在哪一天,哪一科目,所考分数)二.分别解释leftjoin,rightjoin,innerjoin,union1.leftjoin 原理userleftjoinscore=以user表为准,去查询所有user表成员的分数select*fromuserleftjoinscoreonuser.......
  • Linux系统rpm安装MySQL详细操作步骤
    安装方式介绍在Linux系统中,安装软件的方式主要有四种,这四种安装方式的特点如下:安装方式特点二进制发布包安装软件已经针对具体平台编译打包发布,只要解压,修改配置即可rpm安装软件已经按照redhat的包管理规范进行打包,使用rpm命令进行安装(不能自行解决库依赖问题)yum安装一种在线......
  • MySql5.7及以上 ORDER BY 报错问题
    一、问题本人使用的MySql版本是8.0的当MySql5.7及以上的版本执行带有ORDERBY的SQL语句时可能会报错。例如,执行以下mysql语句:SELECTid,user_id,titleFROMm_articleWHEREuser_id>=100ANDuser_id<=200GROUPBYuser_id;SQL报错信息如下:1055-Expression#1o......
  • mysql命令行插入大量数据
    关键字的使用:delimiter定好结束符为"$$",(定义的时候需要加上一个空格)然后最后又定义为";",MYSQL的默认结束符为";"如何通过mysql命令行批量插入100条数据呢,可以在代码里实现,也可以通过命令行,也就是通过存储过程:#第一步:向表user_behavior中插入数据delimiter$$createp......