記遇到的問(wèn)題

  • 1. 問(wèn)題: SQL中數(shù)值類型數(shù)據(jù)和字符串比較蛾娶,會(huì)優(yōu)先取字符串中包含的數(shù)值猫牡,如果不包含數(shù)值則默認(rèn)為0

  • 2. 問(wèn)題:重復(fù)Bean注入org.springframework.beans.factory.NoUniqueBeanDefinitionException
    解決方法:

1. @Qualifier("beanName")
在引用注入時(shí),使用@Qualifier注解來(lái)指定注入

2. @Primary
在定義新的Bean時(shí)旧找,用于聲明優(yōu)先注入
  • 3. 問(wèn)題: SQL中有having函數(shù)作為查詢條件回俐,使用PageHelper插件報(bào)錯(cuò)Unknown column '' in 'having clause'
    原因:因?yàn)?strong>PageHelper插件會(huì)默認(rèn)執(zhí)行一條count(0)統(tǒng)計(jì)語(yǔ)句,此時(shí)會(huì)把原分頁(yè)查詢SQL中的查詢結(jié)果字段替換為count(0)函數(shù)诱建,此時(shí)having函數(shù)用到的字段邊會(huì)不存在導(dǎo)致SQL執(zhí)行報(bào)錯(cuò)
    解決方法:
1. SQL語(yǔ)句中加一個(gè)DISTINT函數(shù)蝴蜓,這樣PageHelper插件執(zhí)行統(tǒng)計(jì)函數(shù)時(shí)便不會(huì)替換查詢字段,而把之前的查詢語(yǔ)句當(dāng)作一個(gè)子表去重新包裹指定統(tǒng)計(jì)函數(shù)

2. 手動(dòng)修改原SQL語(yǔ)句為嵌套的子表查詢
  • 4. 問(wèn)題: 在數(shù)據(jù)庫(kù)中執(zhí)行SELECT * FROM information_schema.innodb_trx;語(yǔ)句查詢?cè)趫?zhí)行中的事務(wù)時(shí)俺猿,出現(xiàn)LOCK WAIT(mysql死鎖)茎匠。
    注: 超過(guò)數(shù)據(jù)庫(kù)配置的鎖等待時(shí)間:innodb_lock_wait_timeout則會(huì)拋出異常LOCK_WAIT_TIMEOUT
    原因一: 高并發(fā)的情況下押袍,Spring事務(wù)造成數(shù)據(jù)庫(kù)死鎖诵冒,后續(xù)操作超時(shí)拋出異常LOCK_WAIT_TIMEOUT
    原因二: MySQL數(shù)據(jù)庫(kù)隔離級(jí)別為可重復(fù)讀(REPEATABLE READ)時(shí)谊惭,Spring的聲明式事務(wù)@Transactional的事務(wù)傳播中存在嵌套事務(wù)(傳播行為如:PROPAGATION_REQUIRES_NEW/PROPAGATION_NESTED)汽馋,主事務(wù)對(duì)A表產(chǎn)生了間隙鎖(Gap Lock),嵌套事務(wù)又對(duì)此表進(jìn)行了更新操作(如:insert/update/delete)正好在在間隙鎖加鎖范圍內(nèi)圈盔,則會(huì)進(jìn)入鎖等待LOCK WAIT(mysql死鎖)豹芯,超過(guò)數(shù)據(jù)庫(kù)配置的鎖等待時(shí)間:innodb_lock_wait_timeout則會(huì)拋出異常LOCK_WAIT_TIMEOUT
    注:間隙鎖(Gap Lock)Innodb可重復(fù)讀(REPEATABLE READ)提交下為了解決幻讀問(wèn)題時(shí)引入的鎖機(jī)制驱敲。

解決方法:

# 應(yīng)急方法:
1. show full processlist; 找出出現(xiàn)問(wèn)題的進(jìn)程铁蹈;
2. kill掉出現(xiàn)問(wèn)題的進(jìn)程。

# 根本解決辦法:
1. select * from information_schema.innodb_trx;  查看有是哪些事務(wù)占據(jù)了表資源
2. 找到對(duì)應(yīng)的程序代碼众眨,如原因二是嵌套事務(wù)導(dǎo)致握牧,可以把主事務(wù)中因?yàn)槲疵兴饕龑?dǎo)致的鎖表操作進(jìn)行修改容诬,避免鎖表

# 其他辦法:
增加鎖等待時(shí)間,即增大下面配置項(xiàng)參數(shù)值沿腰,單位為秒(s) innodb_lock_wait_timeout=500
優(yōu)化存儲(chǔ)過(guò)程览徒,事務(wù)避免過(guò)長(zhǎng)時(shí)間的等待

間隙鎖相關(guān)可參考以下兩篇文章:
間隙鎖詳解
MySQL的鎖機(jī)制 - 記錄鎖、間隙鎖矫俺、臨鍵鎖

  • 5. 問(wèn)題: 處理第三方回調(diào)時(shí)吱殉,需要加鎖(如:分布式鎖redisson)來(lái)保證只處理一次回調(diào)請(qǐng)求(如:易寶支付回調(diào)會(huì)反復(fù)發(fā)送回調(diào)確認(rèn)),如果加鎖和釋放鎖的操作是在事務(wù)內(nèi)部厘托,高并發(fā)情況下會(huì)因?yàn)?strong>鎖釋放了但是事務(wù)沒(méi)提交導(dǎo)致重復(fù)執(zhí)行鎖內(nèi)的代碼片段進(jìn)而影響到數(shù)據(jù)的準(zhǔn)確性
    解決方法:
# 方法一:
在加鎖執(zhí)行的代碼中友雳,新增個(gè)處理標(biāo)記,聲明此段代碼已被處理過(guò)铅匹,無(wú)需重復(fù)處理
如:在redis中設(shè)置個(gè)有期限的唯一標(biāo)識(shí)(有效期根據(jù)實(shí)際運(yùn)行場(chǎng)景規(guī)定)

# 方法二:
可以在存信息的數(shù)據(jù)庫(kù)表中新增唯一索引來(lái)確保數(shù)據(jù)的唯一性

推薦兩種方法一押赊,方法二結(jié)合使用

# 方法三:
把鎖內(nèi)的代碼片段抽取出來(lái)單獨(dú)聲明事務(wù),確保鎖釋放是在事務(wù)提交后進(jìn)行的
  • 6. 問(wèn)題(間隙鎖—場(chǎng)景描述): 秒殺提交訂單為了代碼執(zhí)行效率包斑,把創(chuàng)建易寶訂單(對(duì)接的第三方支付)的步驟放到了生成本地訂單步驟之前流礁。創(chuàng)建易寶訂單的代碼塊是復(fù)用的之前普通下單的,所以有對(duì)訂單的修改操作(用于保存易寶流水號(hào))罗丰,但因?yàn)榇藭r(shí)本地訂單在數(shù)據(jù)庫(kù)中還未生成神帅,所以根據(jù)主鍵的修改操作會(huì)產(chǎn)生間隙鎖。因?yàn)槊霘?chǎng)景又會(huì)有多個(gè)線程同時(shí)在運(yùn)行萌抵,多個(gè)線程同時(shí)執(zhí)行這段代碼塊找御,會(huì)因?yàn)?strong>間隙鎖導(dǎo)致死鎖,這時(shí)在鎖未釋放的時(shí)候绍填,再對(duì)訂單表進(jìn)行插入操作霎桅,則會(huì)直接報(bào)錯(cuò)(Deadlock found when trying to get lock
    注: 數(shù)據(jù)庫(kù)隔離級(jí)別為可重復(fù)讀(REPEATABLE READ)
    解決辦法: 這里是對(duì)“創(chuàng)建易寶訂單”代碼塊里的保存易寶交易單號(hào)信息這段代碼進(jìn)行了非空判斷,對(duì)本地?cái)?shù)據(jù)庫(kù)中不存在的訂單不保存相關(guān)易寶流水號(hào)(可以在易寶后臺(tái)根據(jù)交易訂單號(hào)獲取相關(guān)信息)
# 報(bào)錯(cuò)信息
### Error updating database.  Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
  • 7. 問(wèn)題: sql語(yǔ)句中有空值的列使用in或者not in操作會(huì)失效
    解決辦法:
1. 避免出現(xiàn)空值列(賦予默認(rèn)值)
2. 用 `or` 連接一個(gè)為空的條件 `is null`
例如:column_1 is null or column_1 not in (1,2)
  • 8. 問(wèn)題: Druid連接池配置開(kāi)啟removeAbandoned: true(強(qiáng)制關(guān)閉連接時(shí)長(zhǎng)大于removeAbandonedTimeoutMillis的數(shù)據(jù)庫(kù)連接)讨永,并且removeAbandonedTimeoutMillis(連接最大生命周期)設(shè)置的時(shí)間過(guò)短滔驶,導(dǎo)致數(shù)據(jù)庫(kù)連接被強(qiáng)制關(guān)閉。
    報(bào)錯(cuò)信息
[ERROR] - com.alibaba.druid.pool.DruidDataSource.removeAbandoned(DruidDataSource.java:2979) - abandon connection, owner thread: xxx, connected at : xxx, open stackTrace

解決辦法:

1. 將removeAbandoned這個(gè)配置設(shè)置為false或者不設(shè)置(默認(rèn)就是false)

或者

2. 將removeAbandonedTimeoutMillis這個(gè)時(shí)間配置調(diào)大
# 時(shí)間設(shè)置為30分鐘(單位:秒)
remove-abandoned-timeout: 1800
# 時(shí)間設(shè)置為30分鐘(單位:毫秒)
remove-abandoned-timeout-millis: 1800000
配置 默認(rèn)值 說(shuō)明
removeAbandoned false 是否強(qiáng)制關(guān)閉連接時(shí)長(zhǎng)大于removeAbandonedTimeoutMillis的連接
removeAbandonedTimeoutMillis 300 * 1000 (單位:毫秒) 一個(gè)連接從被連接到被關(guān)閉之間的最大生命周期
logAbandoned false 強(qiáng)制關(guān)閉連接時(shí)是否記錄日志
  • 9. 問(wèn)題:三元表達(dá)式空指針問(wèn)題卿闹,包裝類型自動(dòng)拆箱揭糕,空值null拆箱操作,也就是Integer的intValue()方法報(bào)空指針锻霎。
        DTO dto = new DTO();
        System.out.println(build != null ? build.getProperty() : 1);

解決辦法:

        DTO dto = new DTO();
        System.out.println(build != null ? build.getProperty() : Integer.valueOf(1));
  • 10. 問(wèn)題:Spring事務(wù)默認(rèn)的傳播行為:Propagation.REQUIRED插佛。在使用Spring事務(wù)時(shí),在一個(gè)事務(wù)A中又開(kāi)了一個(gè)事務(wù)B(即存在嵌套事務(wù))量窘,當(dāng)事務(wù)B發(fā)生異常時(shí),在A中將異常catch后事務(wù)B會(huì)進(jìn)行回滾操作氢拥,此時(shí)異常被catch掉蚌铜,事務(wù)A依然會(huì)拋出如上異常并進(jìn)行回滾操作锨侯。
    原因一:因?yàn)閙ethodB的傳播屬性設(shè)置為PROPAGATION_REQUIRED,PROPAGATION_REQUIRED的意思是冬殃,當(dāng)前有事務(wù)囚痴,則使用當(dāng)前事務(wù),當(dāng)前無(wú)事務(wù)則創(chuàng)建事務(wù)审葬。由于methodA的傳播屬性也為PROPAGATION_REQUIRED深滚,所以methodA會(huì)創(chuàng)建一個(gè)事務(wù),然后methodB與methodA使用同一個(gè)事務(wù)涣觉,methodB出現(xiàn)異常后痴荐,將當(dāng)前事務(wù)標(biāo)志位回滾,由于在methodA中做了trycatch處理官册,程序沒(méi)有終止而是繼續(xù)往下走生兆,當(dāng)事務(wù)commit時(shí),check狀態(tài)膝宁,發(fā)現(xiàn)鸦难,需要事務(wù)回滾,所以才會(huì)出現(xiàn)不可預(yù)知的事務(wù)異常:因?yàn)槭聞?wù)被標(biāo)志位回滾员淫,所以事務(wù)回滾合蔽。
    也就是說(shuō):methodA與methodB共用一個(gè)事務(wù),methodB將事務(wù)標(biāo)志為回滾介返,methodA中commit這個(gè)事務(wù)拴事,然后,出現(xiàn)事務(wù)已經(jīng)被標(biāo)志回滾(methodB標(biāo)志的)的異常信息映皆。
    解決辦法:
1. methodA與methodB在邏輯上不應(yīng)該屬于同一個(gè)事務(wù)挤聘,那么將methodB的事務(wù)傳播屬性修改為PROPAGATION_REQUIRES_NEW,這樣捅彻,執(zhí)行methodB時(shí)组去,會(huì)創(chuàng)建一個(gè)新的事務(wù),不影響methodA中的事務(wù)步淹。

2. 業(yè)務(wù)A與業(yè)務(wù)B在業(yè)務(wù)邏輯上就應(yīng)該屬于同一個(gè)事務(wù)从隆,但是methodB的失敗與否不能影響methodA的事務(wù)提交,那么仍然在methodA中try catch methodB,并將methodB設(shè)置為PROPAGATION_NESTED缭裆,它的意思是键闺,methodB是一個(gè)子事務(wù),有一個(gè)savepoint澈驼,失敗時(shí)會(huì)回滾到savepoint辛燥,不影響methodA,如果成功則A、B一起提交挎塌,A與B都是一個(gè)事務(wù)徘六,只是B是一個(gè)子事務(wù)。

Spring事務(wù)報(bào)錯(cuò): org.springframework.transaction.UnexpectedRollbackException

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末榴都,一起剝皮案震驚了整個(gè)濱河市待锈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嘴高,老刑警劉巖竿音,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拴驮,居然都是意外死亡春瞬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門莹汤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)快鱼,“玉大人,你說(shuō)我怎么就攤上這事纲岭∧ㄖ瘢” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵止潮,是天一觀的道長(zhǎng)窃判。 經(jīng)常有香客問(wèn)我,道長(zhǎng)喇闸,這世上最難降的妖魔是什么袄琳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮燃乍,結(jié)果婚禮上唆樊,老公的妹妹穿的比我還像新娘。我一直安慰自己刻蟹,他們只是感情好逗旁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著舆瘪,像睡著了一般片效。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上英古,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天淀衣,我揣著相機(jī)與錄音,去河邊找鬼召调。 笑死膨桥,一個(gè)胖子當(dāng)著我的面吹牛蛮浑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播国撵,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼陵吸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了介牙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤澳厢,失蹤者是張志新(化名)和其女友劉穎环础,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體剩拢,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡线得,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了徐伐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贯钩。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖办素,靈堂內(nèi)的尸體忽然破棺而出角雷,到底是詐尸還是另有隱情,我是刑警寧澤性穿,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布勺三,位于F島的核電站,受9級(jí)特大地震影響需曾,放射性物質(zhì)發(fā)生泄漏吗坚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一呆万、第九天 我趴在偏房一處隱蔽的房頂上張望商源。 院中可真熱鬧,春花似錦谋减、人聲如沸牡彻。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)讨便。三九已至,卻和暖如春以政,著一層夾襖步出監(jiān)牢的瞬間霸褒,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工盈蛮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留废菱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像殊轴,于是被迫代替她去往敵國(guó)和親衰倦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容