You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中while循环内Thread.sleep()后无法获取最新记录问题

Troubleshooting: Loop Not Fetching Updated StoreHeartbeat Records

Hey there, let's break down why your infinite loop isn't picking up the latest database records and fix it step by step.

Common Causes & Fixes

1. Transaction Isolation Level Locking You to Old Data

Most databases default to the Repeatable Read isolation level. If your loop runs within a single ongoing transaction, it'll keep reading the same snapshot of data—even if other transactions update the StoreHeartbeat record. This is a classic "stale read" issue.

Fix:

Ensure each database query runs in a fresh transaction. If you're using Spring, adjust the transaction propagation for your findByStoreId method to force a new transaction every time:

@Service
public class StoreHeartbeatService {
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public StoreHeartbeat findByStoreId(Context context, String locationId) {
        // Your existing query logic here
    }
}

This way, every call to findByStoreId starts a new transaction, bypasses the old data snapshot, and pulls the latest record from the database.

2. ORM Level Caching (e.g., Hibernate First-Level Cache)

If you're using JPA/Hibernate, the first-level cache (tied to the current Session/EntityManager) caches entities after the first fetch. Subsequent queries in the same Session will return the cached, outdated object instead of hitting the database.

Fixes:

  • Refresh the entity after fetching to pull the latest state directly from the database:
    storeHeartbeat = storeHeartbeatService.findByStoreId(context, locationId);
    entityManager.refresh(storeHeartbeat); // Add this if using JPA
    
  • The transaction fix above also helps here, as a new transaction will use a fresh Session/EntityManager.

3. Application-Level Caching (e.g., Spring Cache)

If you added a @Cacheable annotation to your findByStoreId method, your app will return cached results instead of querying the database. This is a super common gotcha!

Fix:

  • Remove the @Cacheable annotation if caching isn't needed for this specific query.
  • If caching is required elsewhere, make sure to evict the cache whenever the StoreHeartbeat record is updated:
    @CacheEvict(value = "storeHeartbeatCache", key = "#locationId")
    public void updateStoreHeartbeat(StoreHeartbeat heartbeat) {
        // Your update logic here
    }
    

Modified Working Loop Example

Here's how your loop might look after applying the transaction and refresh fixes:

// Initial load (ensure this runs in a transaction if needed)
StoreHeartbeat storeHeartbeat = storeHeartbeatService.findByStoreId(context, locationId);
while (true) {
    if (storeHeartbeat.getCurrentHeatbeatDatetime().isAfter(jobTriggeredTime)) {
        break;
    }
    TimeUnit.MILLISECONDS.sleep(300000);
    // Fetch fresh data in a new transaction
    storeHeartbeat = storeHeartbeatService.findByStoreId(context, locationId);
    // Optional: Refresh if using JPA to guarantee latest state
    // entityManager.refresh(storeHeartbeat);
}

内容的提问来源于stack exchange,提问作者Balakrishna R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:51:17