Java提升篇-事务隔离级别和传播机制

问题的提出

为了保证并发操作数据的正确性及一致性,SQL规范于1992年提出了数据库事务隔离级别。

事务隔离级别分类

事务隔离级别由低往高可分为以下几类

  • READ UNCOMMITTED,读取未提交的数据。 这是最不安全的一种级别,查询语句在无锁的情况下运行,并能读取到别的未提交的数据,造成脏读,如果未提交的那个事务数据全部回滚了,而之前读取了这个事务的数据即是脏数据,这种数据不一致性读造成的危害是可想而知的。
  • READ COMMITTED,读取已提交的数据。

一个事务只能读取数据库中已经提交过的数据,解决了脏读问题,但不能重复读,即一个事务内的两次查询返回的数据是不一样的。如第一次查询金额是100,第二次去查询可能就是50了,这就是不可重复读取。

  • REPEATABLE READ,可重复读取数据,这也是Mysql默认的隔离级别。

 一个事务内的两次无锁查询返回的数据都是一样的,但别的事务的新增数据也能读取到。比如另一个事务插入了一条数据并提交,这个事务第二次去读取的时候发现多了一条之前查询数据列表里面不存在的数据,这时候就是传说的中幻读了。这个级别避免了不可重复读取,但不能避免幻读的问题。

  • SERIALIZABLE,可串行化读。

这是效率最低最耗费资源的一个事务级别,和可重复读类似,但在自动提交模式关闭情况下可串行化读会给每个查询加上共享锁和排他锁,意味着所有的读操作之间不阻塞,但读操作会阻塞别的事务的写操作,写操作也阻塞读操作。

上面介绍了4种事务隔离级别及脏读、不可重复读、幻读与它们的联系,对应的关系表如下:

事务隔离级别

脏读

不可重复读

幻读

读取未提交

读取已提交

×

可重复读

×

×

可串行化读

×

×

×

Mysql官方对于事务级别的定义可参考:

https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html

扩展

上面介绍的是Mysql的事务隔离级别,那跟spring中的事务隔离级别有什么必然的联系呢?

spring就是对数据库事务进行了封装而已,并提了5种事务隔离级别和7种事务传播机制。

5种事务隔离级别

ISOLATION_DEFAULT

spring将使用数据库中默认的事务隔离级别。

下面四种定义和上面一致。

ISOLATION_READ_UNCOMMITTED 4 p" L. I' F; k1 {) a. D( E5 ?: V

ISOLATION_READ_COMMITTED

ISOLATION_REPEATABLE_READ

ISOLATION_SERIALIZABLE

7种事务传播机制

REQUIRED

如果当前方法有事务则加入事务,没有则创建一个事务。

NOT_SUPPORTED

不支持事务,如果当前有事务则挂起事务运行。

REQUIREDS_NEW

新建一个事务并在这个事务中运行,如果当前存在事务就把当前事务挂起。新建的事务的提交与回滚一挂起事务没有联系,不会影响挂起事务的操作。

MANDATORY

强制当前方法使用事务运行,如果当前没有事务则抛出异常。

NEVER

当前方法不能存在事务,即非事务状态运行,如果存在事务则抛出异常。

SUPPORTS

支持当前事务,如果当前没事务也支持非事务状态运行。

NESTED

如果当前存在事务,则在嵌套事务内执行。嵌套事务的提交与回滚与父事务没有任务关系,反之,当父事务提交嵌套事务也一起提交,父事务回滚会也回滚嵌套事务的。

如果当前没有事务,则新建一个事务运行,这时候则与PROPAGATION_REQUIRED场景一致。

本文分享自微信公众号 - Java技术栈(javastack)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-06-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏代码GG之家

封装之路(四) BaseFragment BaseViewModel BaseModel

框架实时变更,一直在调整,也是自己的实践过程,继续奋斗了。估计大家对实现没啥兴趣,这节结束,后面直接去github地址看更新了,就不再开贴说了。当这个框架完成时...

241100
来自专栏区块链

腾讯云乐固加固FAQ

注册腾讯云账号成功后找到账号信息,选择绑定QQ或者微信,以后使用PC工具和登录官网时就可以三方快速登录了。

1.8K20
来自专栏北京马哥教育

Linux入侵检查实用指令

1 可以得出filename正在运行的进程 #pidof filename 2 可以通过文件或者tcp udp协议看到进程 #fuser -n tcp port...

45560
来自专栏我的技术专栏

Linux系统编程:基本I/O系统调用

15930
来自专栏文渊之博

关于事务的隔离级别和处理机制的理解

     前几日有一个猎头公司的面试,其中问道我事务隔离这块的知识点,猛一问真是想不起来啊,顿感羞愧啊,回来专门总结一下这方面的知识来夯实一下之前的知识体系,也...

17880
来自专栏木可大大

脏读、不可重复读和幻读现象

对于软件开发人员来说,有时候我们需要面对瞬时海量的并发请求,例如阿里双十一等活动,当处理并发流程时需要我们通过各种机制保持数据一致性,其中,最有效的一种机制就是...

30120
来自专栏向治洪

android混淆和反编译

混淆 Android Studio: 只需在build.gradle(Module:app)中的buildTypes中增加release的编译选项即可,...

28880
来自专栏博客园迁移

事务特性

Consistency:一致性,在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态,即数据完整性约束没有被破坏;比如我们做银...

8610
来自专栏PingCAP的专栏

使用 Ansible 安装部署 TiDB

多机部署 TiDB 太繁琐?快来尝试我们的 TiDB 一键安装吧。本文介绍基于 Ansible Playbook 实现 TiDB 和监控组件的自动化安装和配置,...

1.5K00
来自专栏java达人

关于mysql锁的两个例子

版本:mysql5.5.52 存储引擎:InnoDB 隔离级别:READ-COMMITTED 示例一: 事务1:左图 事务2:右图 1、 ? 事务...

23180

扫码关注云+社区

领取腾讯云代金券