原创博文,欢迎转载,转载时请务必附上博文链接,感谢您的尊重。

前言

通过本篇,你将了解到【Spring事务】与【数据库事务】的关系,以及优先级问题,我将为你一一论证。

阅读本篇,你可能会需要的博文:

  • @Transactional 注解参数详解,以及注解的使用特性说明(典藏版)
  • @Transactional 注解的失效场景,这个问题见过太多的人栽跟头,一篇刨根问底,让面试官都闭嘴
  • 搞定数据库事务、事务的隔离级别,以及脏读、不可重复读、幻读,我是认真的

正文

数据库是可以控制事务的传播和隔离级别的,Spring在之上又进一步进行了封装,可以在不同的项目、不同的操作中再次对事务的传播行为和隔离级别进行策略控制。

所以说,spring事务本质上使用数据库事务,而数据库事务本质上使用数据库锁,所以spring事务本质上使用数据库锁,开启spring事务意味着使用数据库锁。

上面的“总结”来自网络,结合自身理解与实践,的确可以最为一句精华,本文内容主要围绕这句话展开,以2个问题的形式阐明观点。

  1. Spring定义的隔离级别和数据库设置的隔离级别,二者是什么关系?
  2. 如果Spring定义的隔离级别和数据库设置的隔离级别不一样,以谁的为准?

一、两者的关系

详情在我的其他博文都有具体介绍(需要的朋友见本文【前言】提示),这里就不赘述了,我们直接对比结果。

1. 数据库的隔离级别:

MySQL 默认为 :EPEATABLE_READ;Oracle,sql server 默认为:READ_COMMITTED;READ_UNCOMMITTED 由于隔离级别较低,通常不会被使用。

√: 可能出现    ×: 不会出现
隔离级别 隔离级别的值 脏读 不可重复读 幻读
Read uncommitted(未提交读) 0
Read committed(已提交读) 1 ×
Repeatable read(可重复读) 2 × ×
Serializable(可串行化) 3 × × ×

2. Spring事务的隔离级别:

Spring事务由 @Transactional 注解实现,隔离级别由它的参数 isolation 控制,Isolation 的 Eum 类中定义了“五个”表示隔离级别的值,如下。

√: 可能出现    ×: 不会出现
Isolation的值与隔离级别 隔离级别的值 脏读 不可重复读 幻读
Isolation.DEFAULT 0 - - -
Isolation.READ_UNCOMMITTED 1
Isolation.READ_COMMITTED 2 ×
Isolation.REPEATABLE_READ 4 × ×
Isolation.SERIALIZABLE 8 × × ×

Isolation.DEFAULT 是 PlatfromTransactionManager 默认的隔离级别,它的含义是:使用数据库默认的事务隔离级别。

除此之外,另外四个与 JDBC 的隔离级别是相对应的,就好像 Java 里的重写一样,所以说:Spring事务隔离级别是在数据库隔离级别之上又进一步进行了封装。

二、 不一致会怎样

既然是封装,那么Spring项目应该就是以Spring事务为准的,除非使用 @Transactional(isolation = Isolation.DEFAULT)时,才会使用数据库设置的隔离级别。

为了验证这个猜想,我们还是找到源码解读一下,从JDBC开始说起吧。

1. JDBC 加载流程

每一个 Spring 事务管理,都涉及到了与数据库的交互,也必然涉及到了JDBC连接。

JDBC 加载的流程还记得吧,肯定都被问过,有四步:注册驱动,建立连接,发起请求,输出结果。写一段伪代码:

    Connection conn = null;Statement stmt = null;ResultSet rs = null;try{// 1.注册 JDBC 驱动Class.forName("com.mysql.jdbc.Driver");// 2.创建链接System.out.println("连接数据库...");conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/my_db","root","root");// 3.发起请求stmt = conn.createStatement();String sql = "SELECT id, name, url FROM websites";rs = stmt.executeQuery(sql);// 4.输出结果System.out.print("查询结果:" + rs);// 关闭资源(演示代码,不要纠结没有写在finally中)rs.close();stmt.close();conn.close();} catch (SQLException se)se.printStackTrace();}catch(Exception e){e.printStackTrace();}

在创建连接阶段,JDBC 从数据库获取一个连接 Connection 对象,该对象不仅有连接数据库的方法,还有设置当前连接的事物隔离级别的方法。

2. Connection  源码解释

Connection 实体类中包含了 void setTransactionIsolation(int level) throws SQLException;设置设置当前连接的事物隔离级别的方法。

Spring 约定了使用 @Transactional 注解的形式实现事务特性,而隔离级别的开启,也是注解的形式实现,如:开启事务的串行级别 —— @Transactional(isolation = Isolation.SERIALIZABLE)。

源码截不全,我复制一下:

/**
* 这是 Connection 连接的部分源码
*/
public interface Connection  extends Wrapper, AutoCloseable {... /*** 尝试将此连接对象的事务隔离级别更改为给定的级别* 接口连接中定义的常量是可能的事务隔离级别*/void setTransactionIsolation(int level) throws SQLException;...
}

该方法的注释说明:尝试将此连接对象的事务隔离级别更改为给定的级别,如果在事务期间调用此方法,则结果由实现定义。

没错,强调的就是本次连接 Connection,所以,如果spring与数据库事务隔离级别不一致时,以spring为准。

3. 验证

阐述一下方法:

  • 首先,验证测试数据库的隔离级别 Select @@tx_isolation;
  • 写一个包含update,save的与测试数据库交互的方法;
  • 分别验证加上@Transactional(isolation = Isolation.SERIALIZABLE)注解前后,测试数据库的隔离级别是否变化!!

以我的测试数据库为例,结果没有发生变化,都是 READ_COMMITTED。

这只是简单的验证下Spring事务隔离级别的修改,是否会直接影响数据库的隔离级别,结论是没有。

不太严谨,但是证明了我的猜想,后期我会在Sping项目中,通过测试代码进一步验证“修改隔离级别以成功运用到Spring事务中”。

三、总结

  • 数据库是可以控制事务的传播和隔离级别的,Spring在之上又进一步进行了封装,可以在不同的项目、不同的操作中再次对事务的传播行为和隔离级别进行策略控制;
  • 项目中,以 Spring 事务为准,因为他重写了数据库的隔离级别,但没有直接修改数据库的隔离级别;
  • 项目中,如果 Spring 事务隔离级别设置为(isolation = Isolation.DEFAULT)默认数据库优先时,以数据库的隔离级别为准。

小编怀着忐忑的心情,上传了本篇博文,如果有错误,还请大佬指正!!后期也会补全自己的验证手段!!

That's all,thank you!


我是IT无知君,您的点赞、评论和关注,是我创作的动力源泉。
学无止境,气有浩然,让我们一起加油,天涯未远,江湖有缘再见!!

Spring事务隔离级别与数据库隔离级别不一致时,该以谁为准?相关推荐

  1. Spring事务处理,以及Spring事务的传播属性和隔离级别

    本文转自:http://www.cnblogs.com/younggun/archive/2013/07/16/3193800.html 事务的隔离级别:事务隔离级别用于处理多事务并发的情况,通常使用 ...

  2. spring隔离级别与数据库隔离级别

    一.数据库是事务的四大特性(ACID) 1. 原子性: 不可分割的工作单位,要么全部成功要么,全部失败 2. 一致性: 一个事务执行前后,表中数据必须保持一致.比如: 从A账户转账到B账户,不可能因为 ...

  3. Spring事务传播特性与事物隔离级别

    红花易衰似郎意,水流无限似侬愁.--刘禹锡<竹枝词> 传播特性: 传播行为 意义 PROPAGATION_MANDATORY 表示该方法必须运行在一个事务中.如果当前没有事务正在发生,将抛 ...

  4. Spring事务开启方法 传播特性 隔离界别

    1 Spring事务开启方法 1 在Spring配置文件中开启事务并配置事务的类 2 在需要的需要的方法上 或者类上标注@Transactional 2 @Transactional 属性 1 row ...

  5. Spring 事务传播原理及数据库事务操作原理

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 先看看 Spring 事务的基础配置 <beans xmlns="http://www.springframework.org/ ...

  6. Spring事务的传播行为和隔离级别

    ********TransactionDefinition 接口定义******************* /** * Support a current transaction, create a ...

  7. 数据库事务原理详解-数据库隔离级别

    隔离级别 隔离级别的值 导致的问题 Read-Uncommitted 0 导致脏读 Read-Committed 1 避免脏读,允许不可重复读和幻读 Repeatable-Read 2 避免脏读,不可 ...

  8. spring事务@Transactional(readOnly = true)及隔离级别实验

    先写结论: 第一:@Transactional(readOnly = true) 1.那么方法里面,必须是读的操作,当有写的操作的时候会报错提示. 2.读到的数据,从进入方法开始,以后即使其他客户端修 ...

  9. Spring事务管理--(一)数据库事务隔离级别与mysql引擎基础讲解

    一.前言 本篇文章来自网络整理,很简单,但是很实用对于初级和中级工程师. 原创地址1:http://www.cnblogs.com/hollen/archive/2012/05/13/2498309. ...

最新文章

  1. Android中调用另一个Activity并返回结果-以模拟选择头像功能为例
  2. logback Appender详解
  3. 4、表单和高级选择器
  4. 把 SAP UI5 应用部署到 SAP Kyma
  5. ai保存web格式没有html,存储技巧,讲解AI存储为WEB所用格式的一些知识
  6. Emptoris Sourcing Problems
  7. openssl c++实现bouncycastle中AES加解密
  8. 【C语言笔记初级篇】第二章:分支与循环
  9. 支付宝上线小程序,外国人来中国旅游再也不用烦恼了
  10. 苹果挖角Waymo无人车系统主管,奇女子一枚,曾把车开上火星
  11. CoffeeScript简介 一
  12. FMX控件演示(FireMonkey ControlsDemo)
  13. links.php是病毒吗,发现了第一只php病毒PHP.Pirus
  14. PLC网关是什么 PLC网关是做什么的
  15. 华为云学院-人人学loT学习笔记及扩展- 第一章 初识物联网
  16. 一文了解DeFi主经济商,为何说它是DEX主导市场的关键
  17. dirname 使用总结
  18. 谷歌google百度baidu搜索常用指令:inurl,intitle,site,domain,intext,filetype
  19. 小字辈(左子右兄加强版)
  20. 计算机科学应用论文题目,比较好写的计算机科学与应用论文题目 计算机科学与应用论文题目怎么取...

热门文章

  1. $.extend()
  2. 在阿里做了5年技术Leader,我总结出这些套路!
  3. 2FA的完整形式是什么?
  4. 三星4300多功能一体机清零方法
  5. adb修改android设备mac地址
  6. 微信每日推送天气预报每日情话-利用堡塔实现每天自动推送!
  7. 微波遥感7:典型地物
  8. jsp连接数据库一直是null的问题
  9. Laravel 获取腾讯云COS临时密钥
  10. poj1094 Sorting It All Out(拓扑排序+传递闭包)