首页 > 数据库 >MySQL之事务

MySQL之事务

时间:2024-03-04 21:26:06浏览次数:39  
标签:事务 快照 隔离 MySQL 并发 MVCC 级别

事务

什么是事务

事务transaction(简写tx),在数据库中,事务是指一组逻辑操作,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。

事务由事务开始与结束之间执行的全部数据库操作组成。

事务的作用

保证了对数据操作的安全性,保证数据的一致性

例子:还钱的例子

  1. 还钱的账户数据减1000块钱
  2. 被还钱的账户数据增加1000块钱

在操作多条数据的时候可能会出现某几条数据操作不成功的情况

事务的四大特性

事务具有原子性、一致性、隔离性、持久性四大特性,简称ACID

  • 原子性(Atomicity):指事务是一个不可分割的最小工作单位,事务中的操作只有都发生和都不发生两种情况
  • 一致性(Consistency):事务必须使数据库从一个一致状态变换到另外一个一致状态,举一个栗子,李二给王五转账50元,其事务就是让李二账户上减去50元,王五账户上加上50元;一致性是指其他事务看到的情况是要么李二还没有给王五转账的状态,要么王五已经成功接收到李二的50元转账。而对于李二少了50元,王五还没加上50元这个中间状态是不可见的。
  • 隔离性(Isolation):一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  • 持久性(Durability):一个事务一旦提交成功,它对数据库中数据的改变将是永久性的,接下来的其他操作或故障不应对其有任何影响。

注意:只有当前三条性质都满足了,才能保证事务的一致性

如何使用事务

事务相关的关键字

# 1. 开启事务
start transaction;
# 2. 回滚(回到事务执行之前的状态)
rollback;
# 3. 二次确认(确认之后就无法回滚了)
commit;

"""模拟转账功能"""

create table user(
	id int primary key auto_increment,
    name char(16),
    balance int
);
insert into user(name,balance) values
('xiao',10000),
('quan',10),
('zheng',100);

# 1. 先开启事务
start transaction;
# 2. 多条SQL语句
update user set balance=9000 where name='xiao';
update user set balance=110 where name='quan';
update user set balance=1000 where name='zheng';

总结

当你想让多条SQL语句保持一致性,要么同时成功,要么同时失败,那么你就应该考虑使用事务。

小结

原子性,持久性大家基本都能秒懂,隔离性也还好大家稍微想想都能理解,就是接下来要讲的隔离级别,但对一致性很多人被官方概念绕住了,其实就是在多事务并发时要保证数据的一致和完整,不理解的话先看下面的问题。

事务并发带来的4类问题

1、脏读(Dirty Reads)

​ 事务A读取到了事务B修改但尚未提交的数据,然后事务B回滚了,因此事务A基于此数据做的操作都是无效的,就是读到了“脏”数据(实际上不应该存在的数据),所以叫脏读。

2、脏写或丢失更新(Lost Update)

​ 第一类丢失更新:撤销rollback一个事务时,把其他事务已经提交更新的数据回滚掉了。
​ 第二类丢失更新:提交commit一个事务时,把其他事务已经提交更新的数据覆盖掉了。

3、不可重复读(Non-Repeatable Reads)

​ 在事务A中,按相同的条件执行查询过的sql,返回结果发生了修改或被删除了,这种现象就叫做“不可重复读”。

4、幻读(Phantom Reads)

​ 在事务A中,按相同的条件执行查询过的sql,返回结果中有新数据(是其它事务插入的),就好像发生了幻觉一样,这就叫“幻读”。

小结

不可重复读的和幻读很容易混淆,不可重复读侧重于修改或删除,幻读侧重于新增,大家请注意删除不属于幻读。

详细证明请参考

原文链接:https://blog.csdn.net/scm_2008/article/details/127985117

事务4种隔离级别

在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些是在事务内和事务间可见的,哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

每种隔离级别可能出现的问题如下:

事务隔离级别 脏读 不可重复读 幻读
读未提交(RU) 可能 可能 可能
读已提交(RC) 不可能 可能 可能
可重复读(RR) 不可能 不可能 可能
串行化(Serializable) 不可能 不可能 不可能

1、读未提交(Read uncommitted,RU)

最低的隔离级别事务中的修改,即使没有提交,对其他事务也都是可见的,由于可能造成脏读,所以在实际应用中一般很少使用。

2、读已提交(Read committed,RC)

​ 在这个级别下,一个事务只能读取到已经提交的数据,避免了脏读问题。大多数数据库系统的默认隔离级别都是读已提交(像Oracle、PostgreSQL、SqlServer,但Mysql不是)。

3、可重复读(Repeatable read,RR)

Mysql默认的事务隔离级别。在这个级别下,事务开始读取数据后,其他事务无法修改这些数据,保证了同一个事务内两次读取相同记录的一致性,所以解决了脏读和不可重复读问题,但未彻底解决幻读。

4、串行化(Serializable)

可串行化是最高的隔离级别。它通过强制事务串行执行,避免了前面所说的脏读,不可重复读和幻读问题。简单来说,可串行化会在读取的每一行数据上都加上锁,所以可能导致大量的超时和锁争用问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑用该级别。

MVCC机制

什么是MVCC机制

  • MVCC是MySQL InnoDB存储引擎实现的一种基于多版本的并发控制协议,即多版本并发控制。
  • 基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control) 。

MVCC的优势

  • MVCC实现了读不加锁,避免了读写冲突,提高了系统的并发性能。
  • MVCC解决了数据的脏读问题,保证了数据的一致性。

什么是当前读和快照读?

在学习MVCC多版本并发控制之前,我们必须先了解一下,什么是MySQL InnoDB下的当前读和快照读?

  • 当前读

    像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。

  • 快照读

    像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本

说白了MVCC就是为了实现读-写冲突不加锁,而这个读指的就是快照读, 而非当前读,当前读实际上是一种加锁的操作,是悲观锁的实现。

当前读,快照读和MVCC的关系

  • 准确的说,MVCC多版本并发控制指的是 “维持一个数据的多个版本,使得读写操作没有冲突” 这么一个概念。仅仅是一个理想概念。

  • 而在MySQL中,实现这么一个MVCC理想概念,我们就需要MySQL提供具体的功能去实现它,而快照读就是MySQL为我们实现MVCC理想模型的其中一个具体非阻塞读功能。而相对而言,当前读就是悲观锁的具体功能实现。

  • 要说的再细致一些,快照读本身也是一个抽象概念,再深入研究。MVCC模型在MySQL中的具体实现则是由 3个隐式字段,undo日志 ,Read View 等去完成的,具体可以详细看看下面链接叙述的MVCC实现原理

原文链接:https://blog.csdn.net/suchahaerkang/article/details/109389291

标签:事务,快照,隔离,MySQL,并发,MVCC,级别
From: https://www.cnblogs.com/xiao01/p/18052699

相关文章

  • MySQL之索引
    索引知识回顾:数据都是存在于硬盘上的,查询数据不可避免的需要进行IO操作索引:就是一种数据结构,类似于书的目录。意味着以后在查询数据的时候应该先找目录再找数据,而不是一页一页的番薯,从而提升查询熟读降低IO操作。索引在MySQL中也叫“键”,是存储引擎用于快速查找记录的一种数据......
  • MySQL-18 MySQL8其他新特性
    C-18.MySQL8其他新特性1.MySQL8新特性概述MySQL从5.7版本直接跳跃发布了8.0版本,可见是一个令人兴奋的里程碑的版本。MySQL8版本在功能上,做了显著的改进与增强,开发者对MySQL的源代码进行了重构,最突出的一点是对MySQLOptimizer优化器进行了改进。不仅在速度上得到了改善,还为用......
  • C++ mySQL数据库连接池(windows平台)
    C++MySQL数据库连接池新手学了C++多线程,看了些资料练手写了C++数据库连接池小项目,自己的源码地址关键技术点MySQL数据库编程、单例模式、queue队列容器、C++11多线程编程、线程互斥、线程同步通信和unique_lock、基于CAS的原子整形、智能指针shared_ptr、lambda表达式、生产......
  • 【Redis】Redis如何保证和MySQL数据库的数据一致性
    保障MySQL和Redis数据一致性需要使用不同的策略和技术,因为两者是不同的数据存储系统。以下是一些常见的方法:1.数据同步MySQL数据同步至Redis使用事件驱动机制:当MySQL中的数据更新时,通过触发器或者其他事件驱动的机制,将数据同步至Redis。定时任务:定期轮询MySQL数据......
  • mysql语句的执行顺序
    一、sql执行的流程1mysql客户端发送查询请求到服务器。2mysql服务器接收请求并处理,mysql解析器解析查询语句,进行语法分析,确保查询语句符合mysql的语法要求。3mysql的查询优化器对sql语句进行优化处理(选择最合适的索引,或使用其它技术来提高性能),生成执行计划。4mysql执行引......
  • 查询需要使用事务吗?
    查询需要使用事务吗?只有一条查询语句,使用不使用都行..具体看业务场景比如统计报表问题,应该保证的是同一时间维度下,这几条sql语句的查询结果都是当前时刻的.需要开启事务事务隔离级别的选择?RC:对于数据量大的业务,读操作不添加事务,对数据的效率要求高RR:......
  • Ubuntu安装zabbix,初始化数据库报没有这个文件 /usr/share/doc/zabbix-sql-scripts/mys
    报错信息如下: 解决方法:1、先查看是否安装了zabbix-server-mysql,我这里是已经安装过了,但是初始化还是报错找不到文件 2、去zabbix下载对应版本的源码,然后进行手动安装下载链接:https://www.zabbix.com/download_sources#60LTS 3、源码下载后解压,在database文件中找到m......
  • Mysql基本语法笔记
    DDL--操作数据库1.查询SHOWDATABASES;2.创建CREATEDATABASE数据库名称CHARACTERSETutf8;如果不存在创建CREATEDATABASEIFNOTEXISTS数据库名称;3.删除DROPDATABASE数据库名称;如果存在删除DROPDATABASEIFEXISTS数据库名称;4.使用数据库查看当前数......
  • docker环境部署容器之间互通:Hyperf+MySQL
    在docker中要使Hyperf和Mysql网络互通,则需要在创建相应容器的时候指定共享网络,步骤如下:一、首先我们指定共享网络dockernetworkcreate--subnet172.18.0.1/16test  //整条命令复制执行就行不用改这个ip二、创建hyperf命令dockerrun--namehyperf-vD:\hyperf202......
  • MySQL index and dead lock
    MySQL        Analyze:step1.Thread(test1)use"selectforupdate"lockcommonageindexinrange(10,30]step 2.Thread(test2)use"selectforupdate"lockcommonageindexinrange(40,60]step 3.Thread(test2)trytoi......