2026年10月16日,星期五。
今天主要在寫昨天樂觀鎖取號邏輯的單元測試,一直卡在資料未被更新的問題,搞了半天是因為我對「Spring Data JPA 未呼叫Repository.save()但資料卻更新」這個問題的印象記錯了。
我印象中以為「離開method block後,就會自動儲存異動的entity物件狀態(在記憶體)」,所以就沒調用save;但正確應該是「在transaction中,managed entity的狀態異動會透過dirty checking同步至資料庫」,結果好笑的是我沒掛@Transactional。簡單說就是我開10條執行緒,只有第一次無資料時的新增有真的寫進資料庫,後面的執行緒雖然在記憶體中更新了entity,卻沒有把異動存回資料庫。工作環境無法使用AI,所以自己查了一個上午,還以為是Transaction的範圍太大影響什麼的。
public String getNumber() {
int tryCount = 0;
while (tryCount < MAX_TRY_COUNT) {
tryCount++;
try {
OptimisticLockingEntity entity = repository.findBySomeCondition();
if (entity == null) {
// 新增
entity = create();
repository.save(entity);
} else {
// 更新
entity = update(entity);
// repository.save(entity); // 漏了
}
return entity.getNumber();
} catch (Exception e) {
log.warn("Failed to get number, tryCount={}", tryCount, e);
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
log.warn("Failed to get number, interrupted, tryCount={}", tryCount, ie);
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted while retrying", ie);
}
}
}
throw new RuntimeException(
"Failed to get number after " + MAX_TRY_COUNT + " attempts"
);
}
下午休息放風。
給妹妹喝放了好幾天的可樂,已經沒氣了不會刺。
「AI 產品經理學習營」的開訓通知中提到要購買ChatGPT付費版,所以買了ChatGPT Plus並安裝好ChatGPT桌面版,好在明天開始的課程中使用。
沒有留言:
張貼留言