做程序時,如果某個查詢方法應當返回一條記錄,但是查出來多條,是拋異常好還是從多條中取第一條好?

別人手牽手-我牽我的狗


如果某個查詢方法應當返回一條記錄而查出來多條,那麼你第一件要做的事情就是拋出異常,其次要考慮是不是有bug存在於你的軟件系統中。

拋出異常

拋出異常是為了保護程序,保護用戶,保護公司。

假設你是一個登錄系統,需要通過查詢用戶名來讓用戶進行登錄操作,但是查詢方法卻查出了兩個用戶,這個時候你不可能隨便選一個用戶登錄。

假設你是一個銀行系統,有一個用戶A來取錢,銀行系統需要通過銀行卡號來獲取用戶A的餘額信息。當用戶A插入銀行卡後,銀行系統開始查詢用戶信息,但是查詢方法卻返回了兩個用戶信息,這個時候你不可能隨便選一個用戶。

假設你是一個快遞系統,需要通過單號來查詢派送地址信息,但是當你調用查詢方法一個單號卻出現兩個收貨地址,這個時候你不可能隨便選一個地址讓快遞小哥去派送。

考慮bug

當程序執行的結果和你的預期不相同時,你就需要考慮是不是出現了bug。

這個bug可能出現在與你係統任何的角落,此時你需要做的事情就是去一步步調試去定位bug,然後去解決它。

比如說上面的快遞系統,你要考慮為什麼一個訂單出現了兩個收貨地址,是因為存入數據庫時出了差錯還是讀取數據庫時出了差錯或者是其他什麼可能的原因,總之你要不斷地去設想和驗證才能快速的解決bug。

結論

綜上,當一個方法應當返回一條數據但實際卻返回多條時,我的答案就是果斷拋出異常保護系統保護用戶保護公司。


羊羽科技說


你好,我是一名擼碼老手,很高興能回答你的問題,對於程序中本應返回一條記錄的方法,結果返回了多條的情況,我是強烈建議先拋異常,然後查找問題,最後解決問題。


前言

不知道大家有沒有看過《少年包青天》,這部經典的國產懸疑推理片告訴我們一個道理,不管遇到什麼樣的問題,總有它的起因,當然最終也會塵埃落定,因為真相只有一個。


同樣的,在我們寫程序的時候也會遇到這樣那樣的問題(或者說Bug更符合擼碼身份),有時候我們會很煩,甚至想要一度地忽視它,但是它就像一顆雷一樣地暗藏在那裡,隨時都有可能爆掉,可能在調試的時候,也有可能在測試的時候,當然更有可能在上線的時候。


雖然我們總是掩耳盜鈴般地慰藉自己,沒事的,一個小小的Bug而已,影響不大,但有時候就是因為這個小小的Bug可能會損失慘重,這不是誇大其詞,真的是真人真事,曾經有同事因為電話號碼位數的設置不合理,導致手機沒法接撥部分國外地區的電話,從而使得已量產的手機全部返工,損失不小。


所以不管遇到什麼樣的問題,我們都不要抱僥倖心理,要知道墨菲定律無時無刻都在我們身邊,我們要儘量杜絕所有可能發生的情況,特別是不要忽視已經出現的問題。


實戰剖析

一、拋出異常,問題復現

我們假設自己就是那個線上正在操作的幸運兒,操作得正嗨的時候,突然嘣地一聲給你彈了個異常提示框,然後怎麼辦?火急火燎地找客服,然後客服把問題反饋給測試驗證,本地驗證沒問題啊,還是叫開發看一下吧,開發看了錯誤日誌,基本鎖定是數據庫查詢出問題了,本來用的是selectOne方法查詢的,結果查出來的是List,從而導致異常。


  • 在這裡,可能有的小夥伴就建議,沒事幹嘛拋個異常呀,太不友好了,如果有多條記錄,叫開發取最新的那條就好了,對此,我想說,遇到問題,我們要虛心接受並著手解決,而不是規避或逃避問題,當只能有一條記錄的時候,那無論如何都得有且只有一條,而不能特意地去投機取巧,不然可能會爆發更嚴重的問題。

  • 除此之外,我們也要安撫一下那個幸運兒的情緒,並且在一定的酌情考慮下,可以廣發英雄帖,發現問題者給予一定的獎勵,我想大部分的幸運兒都樂意為之的。


二、查找問題根源

發現問題後,開發就百思不得其解,這明明只會有一條記錄的啊,怎麼會在數據庫出現多條呢,哪裡出了問題,代碼?人工?誤操作?根據我多年的經驗以及曾經遇到過類似的問題,來說說可能的情況。

1、有人誤動了數據庫,人為地添加了多條數據。(一般人可能沒這個權限,可能性小)

2、新增該記錄的接口操作引起。(如果沒處理好,高併發情況下可能性很大)

3、其它定時或其它接口操作引起。(如果查詢的記錄所在的數據庫表在其它接口也使用,那這種可能性還是存在的)


以上幾點最有可能的是第2點,因為在高併發的情況下,如果沒有把鎖處理好,以及網絡延遲的情況下是很可能同時插入多條數據的。


三、解決問題

查到了問題的根源,我們就應該一一排查及解決問題,這才是最終問題塵埃落定的時候。

1、核查人員,查找記錄,確認無人動數據庫。

2、在新增記錄的時候,特別是高併發場景,一定要設好互斥鎖,要麼做悲觀鎖,要麼做樂觀鎖,要麼通過緩存來存儲該操作動作,確保某一時刻只有一次操作,然後數據庫可以根據某個字段做一下唯一鍵控制。

3、仔細查看及分析其它可能引起該記錄所在數據庫表的操作代碼。


經過以上幾點排查及處理,我想問題應該已經壽寢正終了。


總結

作為程序猿,遇到Bug不用怕,這只是正常的情況而已,如果開發一個項目一點Bug都沒有,那就真的不敢想象了,遇到問題,查找原因,解決問題,這才是我們該做的。


都市心聲


本人10年開發培訓經驗,期間經歷了Java Web,Android,H5,大數據,PHP等多個不同的方向的開發,也做過軟件培訓公司的金牌講師,很有興趣回答你這個問題。

你這個問題已經把需求說明的很清楚了,”某個查詢方法應當返回一條記錄,但是查出來多條“!也就是說,你的這個查詢只應該有一個結果,但是在此時或者某些時候有了多個結果,那麼就說明你的這個業務接口可能不符合冪等性要求啊。根據冪等性設計原則,無論你怎麼查,只要參數一樣,返回結果應該一樣。

那麼對於這種問題該怎麼解決,拋出異常?返回多條中的第一條?

我覺得都不是很完美的解決方案。

拋異常,這是有些人的一種解決方式,但是問題解決了嗎?沒有啊!問題還在那裡,下次觸發了這個條件,還是會拋異常。這就好比說,森林裡有隻虎,有一天吃了人,然後你不去解決老虎,只是在森林裡掛了個牌子說:慎入,裡面有虎!這......

然後返回多個結果中的第一條,其實這也不是一種好辦法,可能本就應該只返回一條,為什麼查詢到了多個呢?你數據庫裡數據的唯一性做了校驗了嗎?不說別的,每次都查詢多個結果然後拿第一條數據,你不覺得這很影響效率嗎?

所以要從根源上解決問題!為什麼會導致數據有多條?該人工排查數據就人工排查,該加鎖就加鎖,儘可能保證查詢時入參一樣,結果也一樣!


我從事互聯網開發10年,主要的研究方向集中在Java web微服務架構領域,Android移動端研發,HTML5前端方向,我會陸續寫一些關於互聯網技術方面的文章,感興趣的朋友可以關注我,相信你一定會有所收穫。

如果有Java,Android,H5等開發方面的問題,或者是開發求職方面的問題,都可以在評論區留言,或者私信我。


一一哥Sun


異常是什麼?程序運行過程中超出預期行為都屬於異常。

在進行運算( computation)時,出現例外的情況(需要特殊處理的非常規或例外的情況)對應的處理,這種情況經常會破壞程序正常的流程。它通常由特殊的編程語言結構、計算機硬件機制(如:中斷或者如信號等操作系統IPC設施)所構成的。具體實現由硬件和軟件自身定義而決定。一些異常,尤其是硬件,將會在被中斷後進行恢復。

如果某個查詢方法應當返回一條記錄,但是查出來多條應該如何處理?

程序設計的第一要求就可以保證用戶的正常使用。應當返回一條數據,但出現了多條數據,出現這種情況有很多種原因,業務出現問題,數據本身出現髒數據。

此時最好的處理方式,應該保證程序的正常運行,記錄告警消息。需要有檢查異常消息的機制,可以及時跟蹤異常日誌。




極客架構


看業務需求

  • 如果是需要精準數據的話,拋異常無疑。
  • 如果需要的是模糊數據,對於準確性不高,那麼可以隨意獲取一條。

根源解決

接口和得到的數據不統一,如果接口使用正確的話,肯定是數據庫問題,為了業務穩定性,這個一定要解決的。


K哥聊科技


既然已知現象,就應直接程序處理。拋異常是甩包袱行為,而且觸發異常的反應很慢。對這種已知的情況,設計程序邏輯,預先定義如何取結果,或者彈窗口臨時讓用戶決定,都好過拋異常。異常了,還是沒決定到底該怎麼辦,除了結束程序,你還能怎麼樣?下次還拋。我不欣賞那種讓程序用異常來處理錯誤的做法,認為那是懶政,你編程就是要處理各種錯誤和修復的,動不動拋異常終結程序,要你何用。


TonyDeng


這個必須拋異常!按正常邏輯不該出現重複的數據,出現了重複,要麼程序處理中有BUG,要麼數據庫損壞了。如果是前者,有可能是內存洩露,假如對安全性要求高的話,應立即關閉系統以防出現數據洩露的嚴重後果。如果是後者就更糟糕了,這等於損壞了用戶財產,為了防止損失擴大,也應立即停止系統運行,及時分析原因。

以上,說的是上線之後的應對措施。如果還在開發,也應假如相應的異常處理機制才好。


日衝信息 黃


已知問題那就是bug,修正後就不存在問題了。

當然有時候我們只是考慮到這種場景做防禦性編碼,那處理方法就是返回第一條同時輸出ERROR級別的錯誤日誌用於發現問題。


aCHAOS


既然你能預料到可能會查詢出多條數據,那說明是你的框架設計出現了漏洞,作為一個嚴謹的程序員,你應該改善自己的設計,避免這種情況的發生。如果實現難以避免,那也應該用適當的方式讓他通知你這裡有錯誤了


wei3995


不要拋異常,否則會使代碼看起來不那麼優雅。

就是返回第一條記錄,然後在數據庫端刪除多餘數據,再加上唯一性約束。

比如一個電子郵箱地址只能註冊一個用戶。


分享到:


相關文章: