[肥朝]從一次問題排查聊聊問什麼要懂原理

前言

上週五,一同事在開發時遇到了一個問題,叫我幫忙看下.在描述這個同事遇到問題以前,我先簡單作一些知識的鋪墊,不然很差描述.這裏面涉及到的知識點有Spring的事務傳播機制數據庫的隔離級別等.面試

本篇重點是解決同事遇到的問題,由於這兩個知識點都先簡單談談,只爲引出主題.後面這兩個會專門用一篇來說sql

Spring的事務傳播機制

Sring的事務傳播機制有七種,本文涉及到的有兩種數據庫

REQUIRED : 用得最多(估計高達90%),也是默認的模式.若當前沒有事務,則新建事務,若當前已存在一個事務, 則加入到該事務中緩存

REQUIRES_NEW : 新建一個事務bash

Spring的事務傳播機制.後面我會用一篇文章專門來說,給你們列各類典型的題型,按照高中的題型訓練模式,完全弄懂Spring的傳播機制,即便在各類複雜嵌套 + try場景下也能雲淡風輕地肯定回滾狀況.包括解析以前很是經典的一道面試題mybatis

  • 作51次操做,前面50次成功,第51次失敗,所有回滾
  • 作51次操做,前面50次成功,第51次失敗,只回滾第51次,全面50次照常提交

事務的隔離級別

考慮到部分同窗英文問題,我特地標記了中文性能

1.Read Uncommitted: 讀未提交spa

這個基本不可能用,從字面意思你就知道了,讀到別人還未提交的數據,別人都沒提交,你怎麼知作別人接下來是要提交仍是回滾?既然不知道你就讀,天然會有問題.這個問題就是咱們說的髒讀.debug

2.Serializable: 串行化3d

其實就是同步化,性能太差,基本不可能用這個.可是這個是惟一能解決幻讀問題的.

畫圖分析

剩下兩種隔離級別

  • Read Committed: 讀已提交

  • Read Repeatable: 可重複讀

就比較重要了,咱們畫圖來分析

好比我問,當t4時,查詢出來的數據,name是大肥朝仍是toby.其實你心裏就不是很肯定了,可是我若是把提交事務這幾個字加粗標紅,而後引誘一下,絕大多數同窗根本把持不住!!!

既然都提交事務了,那讀出來的天然是toby啦.

其實t4讀出來是toby仍是大肥朝這個取決與你用的是讀已提交可重複讀.其實你從這個中文名稱均可以猜到了,若是是讀已提交,那麼查出來的就是toby.若是是可重複讀.讀出來的天然就是大肥朝. MySQL默認用的是可重複讀.Oracle默認用的是讀已提交.

舒適提示: 這個後面也能夠考慮再寫一篇詳細講一下這個隔離級別,由於通常問到可重複讀,有深度的面試官會繼續追問,可重複讀是如何實現的?具體怎麼實現的咱們能夠先關注肥朝公衆號,後面再具體說數據庫的MVCC機制

問題描述

因爲業務具備必定的複雜度,不利於你們觀看,所以我這裏特地抽象簡化了模型.

首先,我先把數據庫的隔離級別改爲讀已提交.截圖爲證:

那麼問題來了,請問步驟3查詢出來的數據是什麼呢.咱們一塊兒來見證

見證答案

1.查詢完數據,準備更新數據

2.更新完成提交了事務,咱們看得出此時數據庫已經改爲了toby

3.震驚!查出來的數據居然是大肥朝

這個時候彷佛就不厚道了,肥朝你前面怎麼說的,你前面說讀已提交讀出來的是別人已經提交的,那麼應該是toby纔對啊,怎麼仍是大肥朝?.

開始排查

咱們把配置文件設置成`debug級別一切就豁然開朗了

logging.level.com.toby.demo.dao=debug
logging.level.org.mybatis=debug
複製代碼

這裏我特地用不一樣顏色給你們標記清楚了,其實看到只輸出兩次SQL日誌你們就知道了.第三次查詢沒有輸出SQL,這很明顯是用到了Mybatis的緩存了.再根據我標記的SqlSession信息來看,這裏就是用到了Mybatis一級緩存

解決辦法

解決辦法有不少,咱們知道Mybatis一級緩存的做用域是SqlSession,那麼只要兩次查詢是不一樣的SqlSession那天然這個一級緩存就失效了.一級緩存失效了.就會查詢兩次,輸出兩次sql.這個時候是toby仍是大肥朝就真的取決於我前面說的隔離級別了.好比一個簡單的改法是

改法有不少,具體根據那麼的業務來就能夠了,固然也能夠採用上面那種

寫在最後

肥朝 是一個專一於 原理、源碼、開發技巧的技術公衆號,號內原創專題式源碼解析、真實場景源碼原理實戰(重點)。掃描下面二維碼關注肥朝,讓本該造火箭的你,再也不擰螺絲!

相關文章
相關標籤/搜索