博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入浅出数据库事务和4种隔离级别
阅读量:2338 次
发布时间:2019-05-10

本文共 980 字,大约阅读时间需要 3 分钟。

三种bug:

脏读:

例:insert into T values (4, '牛D');,然后没commit。

其他进程SELECT读取到的数据是未commit的数据。(数据库只修改了内存没修改外存)

不可重复读:

例:一个事务范围内两个相同的查询却返回了不同数据(因为中间有进程修改了值并且提交成功)

幻读:

例:某个事务在读取某个范围的数据,但是另一个事务又向这个范围的数据去插入数据,导致多次读取的时候,数据的行数不一致。


  1. READ UNCIMMITTED(未提交读)

    在这种隔离级别下,查询是不会加锁的,也由于查询的不加锁,所以这种隔离级别的一致性是最差的,可能会产生“脏读”、“不可重复读”、“幻读”。


  1. READ COMMITTED(提交读)

    就是只能读到已经提交了的内容。
    为什么提交读,未提交读都没有查询加锁,但是却能够避免脏读呢?

这就要说道另一个机制-快照(snapshot)

当B insert了一条数据然后commit,这时候A执行 select,那么返回的数据中就会有B添加的那条数据......之后无论再有其他事务commit都没有关系,因为照片已经生成了,而且不会再生成了,以后都会参考这张照片。

  • 假设没有“快照读”,那么当一个更新的事务没有提交时,另一个对更新数据进行查询的事务会因为无法查询而被阻塞,这种情况下,并发能力就相当的差。

  • 而“快照读”就可以完成高并发的查询,不过,“读提交”只能避免脏读,并不能避免“不可重复读”(插入INSERT不是更新UPDATE)和“幻读”。

     

     

     


  1. REPEATABLE READ(可重复读)(mysql默认的隔离级别)

    普通的查询同样是使用的“快照读”,但是,和“读提交”不同的是,当事务启动时,就不允许进行“修改操作(Update)”了,而“不可重复读”恰恰是因为两次读取之间进行了数据的修改,因此,“可重复读”能够有效的避免不可重复读,但却避免不了“幻读”,因为幻读是由于“插入或者删除操作(INSERT or DELETE)”而产生的,而不是更新(UPDATE)。


  1. SERIALIZABLE(可串行化)

    这种级别下,事务“串行化顺序执行”,也就是一个一个排队执行。由于他大量加上锁,导致大量的请求超时,因此性能会比较底下,再特别需要数据一致性且并发量不需要那么大的时候才可能考虑这个隔离级别。

 

转载地址:http://ttrpb.baihongyu.com/

你可能感兴趣的文章
默认情况下,如何以管理员身份运行Visual Studio?
查看>>
通过varargs参数可能导致堆污染
查看>>
Git学习笔记1 神奇的git stash
查看>>
Unable to locate package错误解决办法
查看>>
关于service中添加Transaction注解后,service无法注入bean
查看>>
linux shell 自定义函数(定义、返回值、变量作用域)介绍
查看>>
写自己的ASP.NET MVC框架(上)
查看>>
C++和C在linux下编程和与在WINDOWS下有什么区别
查看>>
CSS 的优先级机制[总结]
查看>>
linux shell 数组建立及使用技巧
查看>>
IEnumerator 协程 全称协同程序
查看>>
java实现冒泡排序
查看>>
spring boot 初试,springboot入门,springboot helloworld例子
查看>>
Spring中配置和读取多个Properties文件--转
查看>>
使用JNI进行Java与C/C++语言混合编程(1)--在Java中调用C/C++本地库
查看>>
Mac 终端命令连接mysql
查看>>
Lua中的数学库
查看>>
多态小结
查看>>
Java连MySQL的驱动mysql-connector-java-5.1.21-bin.jar的安装方法
查看>>
java基础小结
查看>>