Re: [請益] 難以偵錯的問題
※ 引述《atpx (秋雨的心情)》之銘言:
: 目前碰到一個棘手的問題.
: 查詢出來的資料, 轉化為物件呈現在頁面上時, 會有部分loss的狀況.
: 例如銷售系統的建立訂單畫面, 可以在欄位內輸入統編,
: 元件用統編查出廠商詳細資料後再帶到前端自動填入其餘欄位.
: 例如廠商名稱/ 地址/ 票期....
: 但是在極少的狀況下, 會發生帶到前端的資料loss(損毀),
: 例如廠商名稱: ABC公司, 呈現在頁面上變成AB, 後面的字都不見了.
^^^^^^^^^^^^^^^^
: user按下儲存後, 就會寫入錯誤的資料, 連帶影響後續功能.
: 頁面已經有檢核必填且不可輸入只能用點選帶值.
: 發生率約幾百分之一, 數百列訂單資料錯一筆.
^^^^^^^^^^
從這兩個特徵來看, 我會往 race condition 的方向猜.
不要覺得 race condition 只會出現在多工環境.
實際上不是, 光是一個簡單的 timed-out operation 就有 racing.
因為要跟時間競賽.
只是寫出 race condition 通常也表示現行架構的細節有問題.
而且如果公司內部沒人對這些細節有概念的話, 那就真的糟糕了.
因為幾乎不可能「『試出』重現錯誤的 test procedure. 」
我會建議你們把整個程式拆開, 先從與資料庫連結的 API 找起.
有些 API 會定義它自己是 atomic operation.
atomic 在這邊的意義就是「絕對不會被打破的」, 八股希臘文. :P
像是各種奇奇怪怪的 mutex/spinlock/semaphore...
還有各式各樣的 data lock.
這用起來很無腦很方便, 前提是要會用, 而且有些系統面的代價.
然後有些 API 說它是 thread-safe.
它會在 thread context 底下保留各自的 environment.
不過這種的就可能做一半被打斷...
所以 threads 之間一樣要有一個明確的資料同步機制.
我要強調一件事, 不少人會把 thread-safe 當成 atomic.
於是造就很多的 racing code——因為把 thread-safe 當成 atomic 用.
最後當然也有很多 API 會標明 thread-unsafe.
這個就懶得說了, thread-unsafe 的問題大家都知道.
不過我個人的猜測是, 這邊查不出問題.
因為大部分的 database API 都已經乾脆幫你包成 atomic operation 了.
更可能出問題的地方, 通常是 framework implementation.
各家 framework 在細節上都會討論到 thread-safe/unsafe 的程度.
不過幾乎都不會去做什麼 atomic operation...
理由很簡單, atomic 要付出的代價是 concurrency 跟 performance.
解這類狀況的答案其實也很簡單: 該同步的地方要同步.
至於甚麼叫做「該同步的地方」... 呃, 大哉問.
我猜你們內部沒有這種概念.
所以才會出現「取 abcdefgh 只拿到 abcd 的結果. 」
因為負責取資料的那段程式只取到一半.
別的程式就已經把資料幹走了.
不要笑, 就連下面這一小段程式碼都可能出現 race condition.
if (event == DO_READ)
lets_fetch_data();
else
lets_show_data();
很奇怪對吧?
因為這段程式碼有可能被包在一個 event handle 裏頭.
而那個寫 handle 的程式員不熟悉他用的 event dispatcher.
於是這邊就出現 event reentrance 的狀況.
我遇過程式員跟我力爭 event 不會重複發送, 我只能說真是沒念書.
現代的 event-driven kernel 幾乎都可以調整.
而 launch kernel 時用了那些參數都沒概念, 還可以東保證西保證也很神奇.
其實 framework 本身都會討論這類的問題.
但是很多程式員都不在意這個(原因幾乎都出於能力不足, 很殘酷地說. )
所以這種東西要靠主管把關...
不過既然問題都出現了, 主管又沒辦法處理的話...
只好建議你們把程式員吊起來打, 或者一個一個地灌辣椒水逼供.
unit test 我想大概做不出結果......
除非你們很清楚要測哪種 synchronous mechanism.
--
新詩練習:新鮮。踩破初春裡的狗大便;不經意的滄桑,滿溢著嫩黃的喜悅。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.101.86
→
06/05 15:04, , 1F
06/05 15:04, 1F
→
06/05 17:04, , 2F
06/05 17:04, 2F
推
06/05 21:00, , 3F
06/05 21:00, 3F
推
06/05 22:17, , 4F
06/05 22:17, 4F
討論串 (同標題文章)