MYSQL数据库之事务
mhr18 2025-01-07 14:25 28 浏览 0 评论
事务
DCL用来控制数据库的访问,包括如下SQL语句:
GRANT:授予访问权限
REVOKE:撤销访问权限
COMMIT:提交事务处理
ROLLBACK:事务处理回退
SAVEPOINT:设置保存点
LOCK:对数据库的特定部分进行锁定
1、事务
思考:我去银行给朋友汇款,我卡上有1000元,朋友卡上500元,我给朋友转账50元(无手续费),如果,我的钱刚扣,而朋友的钱又没加时,网线断了,怎么办?
1.1事务的ACID特性
原子性(Atomicity):原子意为最小的粒子,或者说不能再分的事物。数据库事务的不可再分的原则即为原子性。
组成事务的所有查询必须:要么全部执行,要么全部取消(就像上面的银行例子)。
一致性(Consistency):指数据的规则,在事务前/后应保持一致
隔离性(Isolation):简单点说,某个事务的操作对其他事务不可见的.
持久性(Durability):当事务提交完成后,其影响应该保留下来,不能撤消
1.2事务的用法
开启事务(start transaction)
执行sql操作(普通sql操作)
提交/回滚(commit/rollback)
注意:
l 建表的时候,选择 Innodb引擎才支持事务
默认情况下,MySQL是自动提交事务,每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚。如果某一组操作需要在一个事务中,那么需要使用start transaction,一旦rollback或commit就结束当次事务,之后的操作又自动提交。
如果需要在当前会话的整个过程中都取消自动提交事务,进行手动提交事务,就需要设置set autocommit = false;或set autocommit = 0;那样的话每一句SQL都需要手动commit提交才会真正生效。rollback或commit之前的所有操作都视为一个事务,之后的操作视为另一个事务,还需要手动提交或回滚。
和Oracle一样,DDL语句是不能回滚的,并且部分的DDL语句会造成隐式的提交,因此最好事务中不要涉及DDL语句。
#开启手动处理事务模式
#set autocommit = false;
#开始事务(推荐)
start transaction;
#查看当前表的数据
select * from t_stu_detail;
#删除整张表的数据
delete from t_stu_detail;
#查询该表数据,发现显示删除后的结果
select * from t_stu_detail;
#回滚
rollback
#查看当前表的数据,发现又回来了
select * from t_stu_detail;
#删除整张表的数据
delete from t_stu_detail;
#提交事务
commit;
#查看当前表的数据,发现真删除了
select * from t_stu_detail;
#插入一条记录
INSERT INTO t_stu_detail VALUES
(1, '123456789012345678', '1990-01-21', '12345678901', 'a@163.com', '北七家');
#保存还原点1
savepoint point1;
#插入一条记录
INSERT INTO t_stu_detail VALUES
(2, '123456789012345677', '1990-02-21', '12345678902', 'b@163.com', '北七家');
#保存还原点2
savepoint point2;
#查看当前效果
select * from t_stu_detail;
#回滚到某个还原点
rollback to point1;
#提交事务
commit;
#清空表
truncate t_stu_detail;
#回滚,对于truncate无法回滚
rollback;
#修改表结构
alter table t_stu_detail add description varchar(50);
#回滚,对于修改表结构的语句无法回滚
rollback;
1.3数据库的隔离级别
对于同时运行的多个事务(多线程并发), 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题: (问题的本质就是线程安全问题,共享数据的问题)
脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段. 之后, 若 T2 回滚, T1读取的内容就是临时且无效的.
不可重复读: 对于两个事务 T1, T2, T1 读取了一个字段, 然后 T2 更新并提交了该字段. 之后, T1再次读取同一个字段, 值就不同了.
幻读: 对于两个事务 T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入、删除了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出、少了几行.
数据库事务的隔离性: 数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱。
Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE. Oracle 默认的事务隔离级别为: READ COMMITED
Mysql 支持 4 中事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE-READ
每启动一个 mysql 程序, 就会获得一个单独的数据库连接. 每个数据库连接都有一个变量 @@tx_isolation, 表示当前的事务隔离级别.
查看当前的隔离级别: SELECT @@tx_isolation;
查看全局的隔离级别:select @@global.tx_isolation;
设置当前 mySQL 连接的隔离级别: set tx_isolation ='repeatable-read';
设置数据库系统的全局的隔离级别: set global tx_isolation ='read-committed'; [I1]
隔离级别 | 描述 |
READ-UNCOMMITTED | 允许事务读取其他事务未提交的数据,脏读、不可重复读、幻读的问题都会出现 |
READ-COMMITTED | 只允许事务读取其他事务已经提交的数据,可以避免脏读,但是不可重复读、幻读的问题仍然会出现 |
REPEATABLE-READ | 确保事务可以多次从一个字段中读取相同的值,好比在事务开启时对现有的数据进行了拍照,其他事务对数据的修改,不管事务是否提交,我这里读取的是拍照下来的数据,可以避免脏读和不可重复读,但幻读的问题仍然存在。 注意:INNODB使用了MVCC (Multiversion Concurrency Control),即多版本并发控制技术防止幻读。真正的像拍照一样,其他事务新插入或删除的记录也看不出来。 |
SERIALIZABLE | 确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新、删除操作,所有并发问题都可以避免,但是性能十分低下。 |
1.4示例演示
(1)脏读
脏读:进入餐厅发现“梦中情人”旁边座位已经有“帅哥”坐那儿了,正郁闷,打完饭,发现那个位置是空着的,又欣喜若狂,其实刚刚那个“帅哥”只是临时过去打个招呼。
客户端A却读取到B未提交的脏数据 | 客户端B还未提交 |
客户端A读取不到B未提交的脏数据 | 客户端B还未提交 |
(2)不可重复读
不可重复读:在图书馆门口,发现自己占的位置旁边有位“美女”,等刷完卡,兴冲冲的走到那儿,发现已经变成一“如花”了。
A客户端在同一个事务中,前后两次读取同一条记录,值不同 | B客户端提交了新修改的数据 |
A客户端在同一个事务中,前后两次读取同一条记录,值相同 | B客户端提交了新修改的数据 |
(3)幻读
大学考前画重点,老师说“第一章 xxxxxx概念”,你赶紧找,“天啊,在哪儿啊”,等你画完,就听老师说:“第四章xxxxx”,中间那些你都没听到。
A客户端在同一个事务中,对同一个表的查询记录数不相同 | B客户端事务删除了数据,并提交 |
A客户端在同一个事务中,对同一个表的查询记录数不相同 | B客户端事务添加了数据,并提交 |
(4)序列化
A客户端的事务级别是序列化,A客户端正在查看temp表 | B客户端想要多temp进行增、删、改操作不被允许 如果A客户端迟迟不结束事务,B客户端将会报 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction |
但是B客户端对A客户端未涉及的表不受影响
1.5锁
(1)行级锁
InnoDB的前三个隔离级别是行级锁
如果客户端A在对“id=6”的行进行修改 | B客户端如果也要对“id=6”的行进行修改将会出现等待 |
B客户端如果也要对“id=6”的以外行进行修改不用等
(2)表级锁
InnoDB事务隔离级别是序列化,将会发生整张表的锁
2、 分布式事务
减号不是下划线
相关阅读:
相关推荐
- 订单超时自动取消业务的 N 种实现方案,从原理到落地全解析
-
在分布式系统架构中,订单超时自动取消机制是保障业务一致性的关键组件。某电商平台曾因超时处理机制缺陷导致日均3000+订单库存锁定异常,直接损失超50万元/天。本文将从技术原理、实现细节、...
- 使用Spring Boot 3开发时,如何选择合适的分布式技术?
-
作为互联网大厂的后端开发人员,当你满怀期待地用上SpringBoot3,准备在项目中大显身手时,却发现一个棘手的问题摆在面前:面对众多分布式技术,究竟该如何选择,才能让SpringBoot...
- 数据库内存爆满怎么办?99%的程序员都踩过这个坑!
-
你的数据库是不是又双叒叕内存爆满了?!服务器监控一片红色警告,老板在群里@所有人,运维同事的电话打爆了手机...这种场景是不是特别熟悉?别慌!作为一个在数据库优化这条路上摸爬滚打了10年的老司机,今天...
- springboot利用Redisson 实现缓存与数据库双写不一致问题
-
使用了Redisson来操作Redis分布式锁,主要功能是从缓存和数据库中获取商品信息,以下是针对并发时更新缓存和数据库带来不一致问题的解决方案1.基于读写锁和删除缓存策略在并发更新场景下,...
- 外贸独立站数据库炸了?对象缓存让你起死回生
-
上周黑五,一个客户眼睁睁看着服务器CPU飙到100%——每次页面加载要查87次数据库。这让我想起2024年Pantheon的测试:Redis缓存能把WooCommerce查询速度提升20倍。跨境电商最...
- 手把手教你在 Spring Boot3 里纯编码实现自定义分布式锁
-
为什么要自己实现分布式锁?你是不是早就受够了引入各种第三方依赖时的繁琐?尤其是分布式锁这块,每次集成Redisson或者Zookeeper,都得额外维护一堆配置,有时候还会因为版本兼容问题头疼半...
- 如何设计一个支持百万级实时数据推送的WebSocket集群架构?
-
面试解答:要设计一个支持百万级实时数据推送的WebSocket集群架构,需从**连接管理、负载均衡、水平扩展、容灾恢复**四个维度切入:连接层设计-**长连接优化**:采用Netty或Und...
- Redis数据结构总结——面试最常问到的知识点
-
Redis作为主流的nosql存储,面试时经常会问到。其主要场景是用作缓存,分布式锁,分布式session,消息队列,发布订阅等等。其存储结构主要有String,List,Set,Hash,Sort...
- skynet服务的缺陷 lua死循环
-
服务端高级架构—云风的skynet这边有一个关于云风skynet的视频推荐给大家观看点击就可以观看了!skynet是一套多人在线游戏的轻量级服务端框架,使用C+Lua开发。skynet的显著优点是,...
- 七年Java开发的一路辛酸史:分享面试京东、阿里、美团后的心得
-
前言我觉得有一个能够找一份大厂的offer的想法,这是很正常的,这并不是我们的饭后谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司...
- mysql mogodb es redis数据库之间的区别
-
1.MySQL应用场景概念:关系型数据库,基于关系模型,使用表和行存储数据。优点:支持ACID事务,数据具有很高的一致性和完整性。缺点:垂直扩展能力有限,需要分库分表等方式扩展。对于复杂的查询和大量的...
- redis,memcached,nginx网络组件
-
1.理解阻塞io,非阻塞io,同步io,异步io的区别2.理解BIO和AIO的区别io多路复用只负责io检测,不负责io操作阻塞io中的write,能写多少是多少,只要写成功就返回,譬如准备写500字...
- SpringBoot+Vue+Redis实现验证码功能
-
一个小时只允许发三次验证码。一次验证码有效期二分钟。SpringBoot整合Redis...
- AWS MemoryDB 可观测最佳实践
-
AWSMemoryDB介绍AmazonMemoryDB是一种完全托管的、内存中数据存储服务,专为需要极低延迟和高吞吐量的应用程序而设计。它与Redis和Memcached相似,但具有更...
- 从0构建大型AI推荐系统:实时化引擎从工具到生态的演进
-
在AI浪潮席卷各行各业的今天,推荐系统正从幕后走向前台,成为用户体验的核心驱动力。本文将带你深入探索一个大型AI推荐系统从零起步的全过程,揭示实时化引擎如何从单一工具演进为复杂生态的关键路径。无论你是...
你 发表评论:
欢迎- 一周热门
-
-
Redis客户端 Jedis 与 Lettuce
-
高并发架构系列:Redis并发竞争key的解决方案详解
-
redis如何防止并发(redis如何防止高并发)
-
Java SE Development Kit 8u441下载地址【windows版本】
-
开源推荐:如何实现的一个高性能 Redis 服务器
-
redis安装与调优部署文档(WinServer)
-
Redis 入门 - 安装最全讲解(Windows、Linux、Docker)
-
一文带你了解 Redis 的发布与订阅的底层原理
-
Redis如何应对并发访问(redis控制并发量)
-
Oracle如何创建用户,表空间(oracle19c创建表空间用户)
-
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (83)
- php redis (97)
- redis 存储 (67)
- redis 锁 (74)
- 启动 redis (73)
- redis 时间 (60)
- redis 删除 (69)
- redis内存 (64)
- redis并发 (53)
- redis 主从 (71)
- redis同步 (53)
- redis结构 (53)
- redis 订阅 (54)
- redis 登录 (62)
- redis 面试 (58)
- redis问题 (54)
- 阿里 redis (67)
- redis的缓存 (57)
- lua redis (59)
- redis 连接池 (64)