数据库事务隔离级别

这篇具有很好参考价值的文章主要介绍了数据库事务隔离级别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

标准隔离级别

读未提交、读已提交、可重复读、串行化

串行化

对事务中所有读写的数据加上读锁、写锁、范围锁。所以冲突的事务必须同步执行。

//console1
start transaction ;
select * from transaction_test where `key`=1;
update transaction_test set name='newTest' where `key`=1;
//console2
start transaction ;
select * from transaction_test where `key`=1;(由于事务1没有释放写锁,所以这里的查询会阻塞
如果等待时间过长,会报如下的错误;如果事务1只是查询,那么事务2也可以查询)
[40001][1205] Lock wait timeout exceeded; try restarting transaction
//console1
commit ;(提交完之后如果事务2没有等待超时,那么会立即执行)
//console2;
commit ;

可重复读

核心是只对事务中所有读写的数据加上读锁、写锁,不加范围锁。
相比于读已提交,由于对整个事务都加上了读锁,避免其他事务可以进行更新,进而保证同一个事务多次读到的数据都是没有被修改过的数据。

----避免可重复读----
name初始值为init
//console1
start transaction ;
select * from transaction_test where `key`=1;(查询结果是init)
//console2
start transaction ;
update transaction_test set name='test' where `key`=1;
(理论上,由于事务1已经获取了读锁,事务2这里添加写锁应该是添加不上的,应该是阻塞中才对;
但是,实操发现,执行成功了,且在事务2中通过下面这个语句查询是test,这应该也是mvcc导致的
select * from transaction_test where `key`=1;
//console1
select * from transaction_test where `key`=1;
console1的第2次查询,查询结果和第一次一样,还是init
另外,事务2都获得写锁了,怎么能允许你事务1再去获得读锁
commit ;
//console2
commit ;

相比于串行化,由于没有加范围锁,会引发一种叫幻读的情况
所谓幻读是指在同一个事务中,第一次查询id<10的假定有1条,第二次查询可能会有2条,原因是在两次查询的中间,存在别的事务插入或者删除了数据,由于事务A只加了读锁或者写锁,只能防止其他事务对已经加锁的这几条数据进行修改,但避免不了插入和删除,所以才会出现这个问题。

----幻读----
初始是1,name
//console1
start transaction ;
select * from transaction_test where `key`<10;
//console2
start transaction ;
insert into transaction_test ( `key`,`name`) value (3,'newddd');
select * from transaction_test where `key`<10;
commit;
//console1
select * from transaction_test where `key`<10;
理论上来讲,这个地方应该会查到三条,但是实操发现,在事务2添加并提交之后,事务1查到了依然是原来的样子
即不存在幻读现象,这是怎么回事?
commit ;
select * from transaction_test where `key`<10;(提交之后再次查询就有新结果了)

读已提交

核心是对事务中需要更新的操作行加写锁,直到事务结束,但对查询的操作行加读锁,但在查询完之后立即释放,即不是在整个事务范围锁定。
读已提交通过对查询操作加锁来避免读未提交,在事务B修改数据时因为其在事务结束之前一直持有写锁,事务A无法对数据加读锁,只能等待事务B提交事务才可以读取,这也是读已提交的名称的由来。
虽然解决了读未提交的问题,但是由于只在查询的时候短暂加了读锁,引发了另一个不可重复读的问题;
所谓不可重复读是指在同一个事务中,对于同样一条数据的两次查询结果不一样,那么这个和幻读有什么区别呢?幻读整个事务中都存在读锁或者写锁,其他事务无法修改,只能增删;但是不可重复读,则是指当前已经查到的结果被更新了。
原因是假如同一个事务两次查询中间,别的事务进行了修改,由于事务A没有加整个事务范围的读锁,所以事务B是可以成功获取写锁的,进而修改数据,最终导致了不可重复读。

---避免读未提交----
name初始值是init
//console1
start transaction ;
select * from transaction_test where `key`=1;
update transaction_test set name='test' where `key`=1;
//console2
start transaction ;
select * from transaction_test where `key`=1;(由于读不到未提交的,所以肯定获取不到修改后的test值,理论上只能等待事务1结束)
这个地方由于事务1已经添加了写锁,原则上事务2根本查询不了,应该阻塞,就像串行化那里一样
但是实际结果却是可以查到以前的值,即init;所以这里应该是mvcc的作用
在读已提交的级别下,mvcc机制总是取最新的版本即可,即最近被 Commit 的那个版本的数据记录。
这样保证了读到的都是已提交的事务,且保留了幻读问题
最新版本的快照读,不是当前读
//console1
commit;//提交之后,事务2再次查询,发现已经可以获取到改动后的值了,即test

---不可重复读----
name初始值是init
//console1
start transaction ;
select * from transaction_test where `key`=1;(第一次查询是init)
//console2
start transaction ;
update transaction_test set name='test' where `key`=1;(在事务2中更新并提交)
commit ;
//console1
select * from transaction_test where `key`=1;(第二次查询是test)
commit ;

读未提交

核心是对事务中需要更新的操作行加写锁,直到事务结束,但对查询的操作行不加锁。
引发的问题是脏读,其实就是读到了其他事务还没有提交的数据;那么为什么事务A可以读到事务B还没有提交的数据?
分为两步理解:
1.为什么存在可以读的新的数据?
核心原因应该是write-ahead logging的设计。即上一章提到的允许在事务提交之前提前写入数据,理论上肯定是写到了内存中,并且记录到undolog里面,虽然还不太情况事务的提交真正干了什么操作,但目前来,在内存是可以读到已经修改好的数据。
2.为什么可以读到已经加了写锁的数据
原因是读未提交读取数据是不加读锁的,而写锁只能防止其他事物不能加读锁和写锁,而不能防止没有锁 也可以看一下
读未提交-为什么事务没提交就可以读到别人修改的数据

show variables like 'transaction%';
set global transaction isolation level read uncommitted ;//设置完之后要重新登录
CREATE TABLE `transaction_test` (
`key` int(11),
`name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB;
---read uncommitted---
读未提交
//console1
start transaction ;
insert into transaction_test value (1,'test');
//console2
start transaction ;
select * from transaction_test where `key`=1; (查询结果为1,test)
//console1
commit ;
//console2
commit;

两个事务都是写事务,晚开启的事务更新会阻塞
//console1
start transaction ;
update transaction_test set name='newTest' where `key`=1;
//console2
start transaction ;
update transaction_test set name='Test' where `key`=1;(会阻塞,一直在执行中)
//console1
commit ;(在事务1提交成功后,事务2的更新立马就成功了)
//console2
commit;

参考资料:

12 | 本地事务如何实现隔离性?-极客时间
03 | 事务隔离:为什么你改了我还看不见?-极客时间
读未提交-为什么事务没提交就可以读到别人修改的数据 - 秦一居 - 博客园文章来源地址https://www.toymoban.com/news/detail-477316.html

到了这里,关于数据库事务隔离级别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据库事务的四种隔离级别

    事务 数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单元,由一个有限的数据库操作序列构成。——维基百科 简而言之:一系列数据库操作语句组成事务。 数据库事务的隔离级别有四种: 读未提交(Read Uncommitted):事务中的修改可以被其他事务读取,

    2024年02月04日
    浏览(44)
  • 【Spring/MySQL数据库系列】数据库事务的特点与隔离级别

    ⭐️ 前面的话 ⭐️ 本文已经收录到《Spring框架全家桶系列》专栏,本文将介绍有关数据库事务的特点以及隔离级别。 📒博客主页:未见花闻的博客主页 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 📌本文由 未见花闻 原创, CSDN 首发! 📆首发时间:🌴2023年5月20日🌴 ✉️坚

    2024年02月05日
    浏览(55)
  • 【后端面经-数据库】MySQL的事务隔离级别简介

    目录 0. 事务的概念 1. 三类问题 2. 事务隔离级别 3. 操作指令 4. 总结 5. 参考博文 事务指的是一连串的集中操作指令,一个事务的执行必须执行完所有的动作才能算作执行结束。事务具有四个特点,简记作 ACID : A -Atomicity: 原子性,事务的执行必须保证所有的动作都执行完毕;

    2024年02月08日
    浏览(49)
  • 聊一聊数据库事务的那些事(隔离级别,传播行为)

      我们平时使用事务的时候,可能脑子里面想到和事务有关的知识点无非就是,ACID,事务隔离级别那一套,使用的事务也就是是通过注解的形式,或者手动开启事务。更细致一点的问题或许没有深究下去,比如事务的传播行为,注解形式和手动事务的区别等,今天我们就这几

    2024年02月07日
    浏览(57)
  • 【Mysql数据库 第13章】MySQL的事务、事务的隔离级别、事务的保存点

    💖Spring中的创建对象的三种方式、第三方资源配置管理详细描述及使用(XML版完结篇) 💖Spring中的bean的配置、作用范围、生命周期详细描述及使用(XML版上篇) 💖

    2023年04月20日
    浏览(56)
  • elasticsearch的查询方式和mysql数据库事务隔离级别的思考

    目录 普通分页 解除查询限制 scroll查询 search_after 官方改进 轻量级试图(pit,Point in time) 总结 项目中用到了 elasticsearch,发现有几种查询方式不太一样,思考了一下,总结如下 等同于关系数据库的分页查询,例如 mysql 的 limit,如下 sql 这种查询方式有一个问题,需要查询

    2024年01月18日
    浏览(51)
  • 数据库四种事务隔离级别的区别以及可能出现的问题

    当两个或多个事务读入同一数据并修改,会发生丢失修改问题,前一个事务修改的结果会被后一事务所做的修改覆盖。 当一个事务修改某个数据后,另一事务对该数据进行了读取,由于某种原因 前一事务撤销 了对该数据的修改,即将修改后的数据恢复原值,相当于没有执行

    2024年02月07日
    浏览(76)
  • 事务的四个特性、四个隔离级别以及数据库的常用锁

    事务的四个特性、四个隔离级别以及数据库的常用锁 四大特性 事务的四大特性,通常被称为ACID特性,是数据库管理系统(DBMS)确保事务处理的关键属性。这四大特性分别是: 原子性(Atomicity): 原子性要求事务是一个不可分割的单位,要么全部执行,要么全部不执行。如

    2024年02月04日
    浏览(48)
  • MySQL数据库中,在读已提交和可重复读这两个不同事务隔离级别下幻读的区别

    在正式开始之前,先简单回顾一下并发事务存在的问题以及事务的隔离级别等内容。 1.1 并发事务存在的问题 当两个或者两个以上事务同时开启去处理同一个表的数据时,可能会存在以下的问题: 丢失修改 脏读 不可重复读 幻读 丢失修改 丢失修改是指当两个或多个事务更新

    2024年02月02日
    浏览(56)
  • 数据库隔离级别

    1.1 事务 事务只是一个改变,是一些操作的集合;用专业的术语讲,他就是一个程序的执行单元; 事务本身其实并不包含这4个特性 ,只是我们需要通过某些手段,尽可能的让这个执行单元满足这四个特性,那么我们就可以称它为一个事务,或者说是一个正确的事务,完美的

    2024年02月07日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包