十二、MySql的事务(下)

文章目录

  • 一、事务隔离级别
  • 二、如何理解隔离性
  • 三、隔离级别
    • (一)读未提交【Read Uncommitted】:
    • (二)读提交【Read Committed】 :
    • (三)可重复读【Repeatable Read】:
    • (四)串行化【Serializable】:
  • 四、查看与设置隔离性
    • (一)查看全局隔离级别
    • (二)查看会话(当前)全局隔离级别
    • (三)设置全局隔离性,另起一个会话,会被影响
    • (四)隔离级别详解
      • 1.读未提交【Read Uncommitted】
      • 2.读提交【Read Committed】
      • 3.可重复读【Repeatable Read】
      • 4.串行化【serializable】
      • 5.总结
    • (五)一致性

一、事务隔离级别

二、如何理解隔离性

  • MySQL服务可能会同时被多个客户端进程(线程)访问,访问的方式以事务方式进行
  • 一个事务可能由多条SQL构成,也就意味着,任何一个事务,都有执行前,执行中,执行后的阶段。而所谓的原子性,其实就是让用户层,要么看到执行前,要么看到执行后。执行中出现问题,可以随时回滚。所以单个事务,对用户表现出来的特性,就是原子性。
  • 但,毕竟所有事务都要有个执行过程,那么在多个事务各自执行多个SQL的时候,就还是有可能会出现互相影响的情况。比如:多个事务同时访问同一张表,甚至同一行数据。
  • 就如同你妈妈给你说:你要么别学,要学就学到最好。至于你怎么学,中间有什么困难,你妈妈不关心。那么你的学习,对你妈妈来讲,就是原子的。那么你学习过程中,很容易受别人干扰,此时,就需要将你的学习隔离开,保证你的学习环境是健康的。
  • 数据库中,为了保证事务执行过程中尽量不受干扰,就有了一个重要特征:隔离性
  • 数据库中,允许事务受不同程度的干扰,就有了一种重要特征:隔离级别

三、隔离级别

(一)读未提交【Read Uncommitted】:

在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等,我们上面为了做实验方便,用的就是这个隔离性。

(二)读提交【Read Committed】 :

该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select, 可能得到不同的结果

(三)可重复读【Repeatable Read】:

这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是会有幻读问题。

(四)串行化【Serializable】:

这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,但是可能会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)。

隔离级别如何实现:隔离,基本都是通过锁实现的,不同的隔离级别,锁的使用是不同的。常见有,表锁,行锁,读锁,写锁,间隙锁(GAP),Next-Key锁(GAP+行锁)等。不过,我们目前现有这个认识就行,先关注上层使用。

四、查看与设置隔离性

-- 设置当前会话 or 全局隔离级别语法
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

(一)查看全局隔离级别

mysql> SELECT @@global.tx_isolation; --

在这里插入图片描述

(二)查看会话(当前)全局隔离级别

mysql> SELECT @@session.tx_isolation;--查看会话(当前)全局隔级别
mysql> SELECT @@tx_isolation; --默认同上

在这里插入图片描述

(三)设置全局隔离性,另起一个会话,会被影响

set global transaction isolation level READ UNCOMMITTED;

(四)隔离级别详解

1.读未提交【Read Uncommitted】

--几乎没有加锁,虽然效率高,但是问题太多,严重不建议采用
--终端A
--设置隔离级别为 读未提交
mysql> set global transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
--重启客户端
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set, 1 warning (0.00 sec)
mysql> select * from account;
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1 | 张三 | 100.00 |
读提交【Read Committed】
| 2 | 李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
mysql> begin; --开启事务
Query OK, 0 rows affected (0.00 sec)
mysql> update account set blance=123.0 where id=1; --更新指定行
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
--没有commit哦!!!
--终端B
mysql> begin;
mysql> select * from account;
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1  | 张三  | 123.00 | --读到终端A更新但是未commit的数据[insert,
delete同样]
| 2  | 李四  | 10000.00|
+----+--------+----------+
2 rows in set (0.00 sec)

一个事务在执行中,读到另一个执行中事务的更新(或其他操作)但是未commit的数据,这种现象叫做脏读(dirty read)!

2.读提交【Read Committed】

mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
--重启客户端
mysql> select * from account; --查看当前数据
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1 | 张三 | 123.00 |
| 2 | 李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
mysql> begin; --手动开启事务,同步的开始终端B事务
Query OK, 0 rows affected (0.00 sec)
mysql> update account set blance=321.0 where id=1; --更新张三数据
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
--切换终端到终端B,查看数据。
mysql> commit; --commit提交!
Query OK, 0 rows affected (0.01 sec)
--切换终端到终端B,再次查看数据。
--终端B
mysql> begin; --手动开启事务,和终端A一前一后
Query OK, 0 rows affected (0.00 sec)
mysql> select * from account; --终端A commit之前,查看不到
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1 | 张三 | 123.00 | --老的值
| 2 | 李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
--终端A commit之后,看到了!

but,此时还在当前事务中,并未commit,那么就造成了,同一个事务内,同样的读取,在不同的时间段(依旧还在事务操作中!),读取到了不同的值,这种现象叫做不可重复读(non reapeatable read)!!(这个是问题吗??)

3.可重复读【Repeatable Read】

--终端A
mysql> set global transaction isolation level repeatable read; --设置全局隔离级别
RR
Query OK, 0 rows affected (0.01 sec)
--关闭终端重启
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ | --隔离级别RR
+-----------------+
1 row in set, 1 warning (0.00 sec)
mysql> select *from account; --查看当前数据
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1 | 张三 | 321.00 |
| 2 | 李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
mysql> begin; --开启事务,同步的,终端B也开始事务
Query OK, 0 rows affected (0.00 sec)
mysql> update account set blance=4321.0 where id=1; --更新数据
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
--切换到终端B,查看另一个事务是否能看到
mysql> commit; --提交事务
--切换终端到终端B,查看数据。
--终端B
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from account; --终端A中事务 commit之前,查看当前表中数据,数据未更新
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1  | 张三 | 321.00 |
| 2 | 李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
mysql> select * from account; --终端A中事务 commit 之后,查看当前表中数据,数据未更新
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1  | 张三 | 321.00  |
| 2  | 李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
--可以看到,在终端B中,事务无论什么时候进行查找,看到的结果都是一致的,这叫做可重复读!
mysql> commit; --结束事务
Query OK, 0 rows affected (0.00 sec)
mysql> select * from account; --再次查看,看到最新的更新数据
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1 | 张三 | 4321.00 |
| 2 | 李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)
----------------------------------------------------------------
--如果将上面的终端A中的update操作,改成insert操作,会有什么问题??
--终端A
mysql> select *from account;
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1 | 张三 | 321.00 |
| 2 | 李四 | 10000.00 |
+----+--------+----------+
2 rows in set (0.00 sec)

4.串行化【serializable】

--对所有操作全部加锁,进行串行化,不会有问题,但是只要串行化,效率很低,几乎完全不会被采用
--终端A
mysql> set global transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE   |
+----------------+
1 row in set, 1 warning (0.00 sec)
mysql> begin; --开启事务,终端B同步开启
Query OK, 0 rows affected (0.00 sec)
mysql> select * from account; --两个读取不会串行化,共享锁
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1 | 张三 | 4321.00  |
| 2 | 李四 | 10000.00 |
| 3 | 王五 | 5432.00  |
+----+--------+----------+
3 rows in set (0.00 sec)
mysql> update account set blance=1.00 where id=1; --终端A中有更新或者其他操作,会阻
塞。直到终端B事务提交。
Query OK, 1 row affected (18.19 sec)
Rows matched: 1 Changed: 1 Warnings: 0
--终端B
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from account; --两个读取不会串行化
+----+--------+----------+
| id | name | blance |
+----+--------+----------+
| 1 | 张三 | 4321.00  |
| 2 | 李四 | 10000.00 |
| 3 | 王五 | 5432.00  |
+----+--------+----------+
3 rows in set (0.00 sec)
mysql> commit; --提交之后,终端A中的update才会提交。
Query OK, 0 rows affected (0.00 sec)

在这里插入图片描述

5.总结

  • 其中隔离级别越严格,安全性越高,但数据库的并发性能也就越低,往往需要在两者之间找一个平
    衡点。
  • 不可重复读的重点是修改和删除:同样的条件, 你读取过的数据,再次读取出来发现值不一样了
    幻读的重点在于新增:同样的条件, 第1次和第2次读出来的记录数不一样
  • 说明: mysql 默认的隔离级别是可重复读,一般情况下不要修改上面的例子可以看出,事务也有长短事务这样的概念。事务间互相影响,指的是事务在并行执行的时候,即都没有commit的时候,影响会比较大。

(五)一致性

  • 事务执行的结果,必须使数据库从一个一致性状态,变到另一个一致性状态。当数据库只包含事务成功提交的结果时,数据库处于一致性状态。如果系统运行发生中断,某个事务尚未完成而被迫中断,而改未完成的事务对数据库所做的修改已被写入数据库,此时数据库就处于一种不正确(不一致)的状态。因此一致性是通过原子性来保证的。
  • 其实一致性和用户的业务逻辑强相关,一般MySQL提供技术支持,但是一致性还是要用户业务逻辑做支撑,也就是,一致性,是由用户决定的。
  • 而技术上,通过AID保证C。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142970.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机网络笔记六】应用层(三)HTTP 的 Cookie、缓存控制、代理服务、短连接和长连接

HTTP 的 Cookie HTTP 的 Cookie 机制要用到两个字段:响应头字段 Set-Cookie 和请求头字段 Cookie。 Cookie 可以设置多个 key-value 对, 响应头中可以设置多个 Set-Cookie 字段,请求头Cookie后面可以设置多个键值对,用分号隔开&a…

西门子KTP触摸屏做画面时如何把设备图片或Logo做到画面上?

西门子KTP触摸屏做画面时如何把设备图片或Logo做到画面上? 如下图所示,新建一个项目,添加一个触摸屏设备,这里以TP1200 Comfort触摸屏为例进行说明,双击进入根画面, 如下图所示,在右侧的工具箱中…

学习路之工具--SecureCRT的下载、安装

百度盘: 链接: https://pan.baidu.com/s/1r3HjEj053cKys54DTqLM4A?pwdgcac 提取码: gcac 复制这段内容后打开百度网盘手机App,操作更方便哦 感谢大佬 简单介绍下SecureCRT SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序&a…

[C++ 网络协议] 多线程服务器端

具有代表性的并发服务器端实现模型和方法: 多进程服务器:通过创建多个进程提供服务。 多路复用服务器:通过捆绑并统一管理I/O对象提供服务。 多线程服务器:通过生成与客户端等量的线程提供服务。✔ 目录 1. 线程的概念 1.1 为什…

静态链接与动态链接

目录 静态链接 地址空间分配 静态链接的详细过程 静态链接库 动态链接 位置无关代码 延迟绑定机制 本篇会重点介绍静态链接,动态链接,延迟绑定机制 问:两个或者多个不同的目标文件是如何组成一个可执行文件的呢? 答:这就…

数据结构 - 线段树的运用

数据结构 - 线段树的运用 前言一. 线段树的运用1.1 区间和 - 线段树节点的成员变量1.2 线段树的构建1.3 线段树的区间和查询1.4 线段树的区间和更新1.5 完整代码 二. 线段树的动态扩建2.1 向下递推2.2 向上递推2.3 更新操作2.4 查询操作2.5 完整代码 三. 线段树的使用案例3.1 定…

Unity之NetCode多人网络游戏联机对战教程(3)--NetworkObject组件讲解

文章目录 NetworkObjectAlways Replicate As RootSynchronization TransformActive Scene SynchronizationScene Migration SynchronizationSpawn With ObserversDont Destroy With OwnerAuto Object Parent Sync 后话 NetworkObject 为了复制任何Netcode感知属性或发送/接收R…

Python大数据之pandas快速入门(一)

文章目录 pandas快速入门学习目标1. DataFrame 和 Series 简介2. 加载数据集(csv和tsv)2.1 csv和tsv文件格式简介2.2 加载数据集(tsv和csv) pandas快速入门 学习目标 能够知道 DataFrame 和 Series 数据结构能够加载 csv 和 tsv 数据集能够区分 DataFrame 的行列标签和行列位…

FPGA project : uart232_ram_vga

重点学习: 本实验重点学习了双口ram解决多bit跨时钟域同步处理的问题。 其实signal port ram,它的输入口和输出口分别用不同的时钟,也可以解决这个问题。 让我意识到的比较重要的事情: 1,代码设计中,一…

经典题记录 字符串相加/相乘

1. LeetCode 415 字符串相加 代码一:代码简短,但需要借助额外的一个string来保存结果,更占用内存。 class Solution { public:string addStrings(string num1, string num2) {string ans"";int size1num1.size();int size2num2.si…

Qt_C++读写NFC标签Ntag支持windows国产linux操作系统

本示例使用的发卡器&#xff1a;Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/智能海报/-淘宝网 (taobao.com) ntag2标签存储结构说明 #include "mainwindow.h" #include "./ui_mainwindow.h" #include <QDebug> #include "QLibrary&…

Django REST Farmowork初探

1.简介 Django REST framework &#xff08;简称&#xff1a;DRF&#xff09;是一个强大而灵活的 Web API 工具。 遵循RESTFullAPI风格&#xff0c;功能完善&#xff0c;可快速开发API平台。 官网文档&#xff1a;https://www.django-rest-framework.org 2. framwork的安装 …

界面组件DevExpress WPF v23.2新功能预览 - 更轻量级的主题

本文主要描述了DevExpress WPF即将在几个月之后发布的v23.2中包含的新功能&#xff0c;持续关注我们获取更多最新资讯哦~ P.S&#xff1a;DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强…

2023蓝帽杯半决赛取证复现

1.检材数据开始提取是今年什么时候&#xff1f;&#xff08;答案格式&#xff1a;04-12 13:26&#xff09; 09-11 17:21 这题做错了 其实当时盘古石手机取证里面就有的&#xff0c;想多了去看了日志文件 是真的有点歧义&#xff0c;20分就开始提取任务了 2.嫌疑人手机SD卡存…

精通git,没用过git cherry-pick?

前言 git cherry-pick是git中非常有用的一个命令&#xff0c;cherry是樱桃的意思&#xff0c;cherry-pick就是挑樱桃&#xff0c;从一堆樱桃中挑选自己喜欢的樱桃&#xff0c;在git中就是多次commit中挑选一个或者几个commit出来&#xff0c;也可以理解为把特定的commit复制到…

【实验记录】AGW | Visible-Infrared Re-ID

【RT】Visible Thermal Re-IDDeep Learning for Person Re-identification: A Survey and Outlook中提出了一个针对单/跨模态行人重识别的baseline&#xff1a;AGW 做过两次&#xff0c;在测试阶段有问题&#xff0c;现在再重做一次&#x1f914;Code RTX3090 修改数据集路…

手机相机系统介绍

目录 一张照片是如何生成的? 相机的成像原理 相机硬件 颜色四要素 相机硬件三大块 模组结构 镜头 镜头光路 镜头常见参数 镜头-FOV&EFL 镜头-焦距 镜头-光圈 图像传感器 图像传感器-像素-底 RGB排布 图像传感器-Pattern & PDAF Sensor CMOS sensor …

计算机类软件方向适合参加的比赛

前言 博主是一名计算机专业的大三学生&#xff0c;在校时候参加了很多比赛和训练营&#xff0c;现在给大家博主参加过的几个的比赛&#xff0c;希望能给大一大二的学生提供一点建议。 正文 最近也有比赛的&#xff0c;我会从时间线上来给大家推荐一些比赛&#xff0c;并且给…

雷柏mv20鼠标使用体验

用了1年多&#xff0c;第一次用竖着的鼠标&#xff0c;现在已经很习惯了&#xff0c;感觉还不错。说说使用感受&#xff1a; 1、 仍然是长时间使用鼠标&#xff0c;但是很少出现手腕痛的情况&#xff0c;确实是有一定效果的。 2、使用场景是有限制的&#xff0c;我是配合笔记…

解决kali beef启动失败问题及实战

文章目录 一、解决方法二、靶场实战应用1.首先打开dvwa这个靶场&#xff0c;设置难度为low2.打开xss-stored3.准备payload4.提交payload5.利用 一、解决方法 首先需卸载 ruby apt remove ruby 卸载 beef apt remove beef-xss 重新安装ruby apt-get install ruby apt-get insta…