多次重复调用 DAO 后返回空数据集

Empty data set returned after a few repeated calls to DAO

我遇到了一个严重的问题,DAO 层在几次调用后停止返回记录。我正在使用 Spring Framework 5.3.10。涉及的主要组件是:

我有一个 Spring 控制器 (A),它反复(每 2 - 3 秒)异步调用 Spring 服务 (B) 的方法(标有 @Async 的方法)以及每次调用的不同参数。有一个 DAO 层 (C) 声明为 Spring 服务。 Spring 服务 (B) 中的工作者方法在每个 运行 的开头调用一个 DAO 方法,从数据库 table 中检索与传递的参数对应的数据集。在Spring服务(B)中worker方法执行结束时,更新入参对应的行(不是入参对应的字段)。 Spring服务中的方法(B)处理数据的时间比较长,大概10-15秒。

在来自 Spring 控制器 (A) 的大约第三次或第四次调用之后,对 DAO 方法的调用 returns 一个空结果集。在Spring服务(B)中缓慢调用方法时,等待前面的调用完成,一切正常。

设置事务隔离没有任何效果。

我已经尝试解决这个问题几天了,但一无所获。如果有人能指出正确的方向如何解决这个问题,我将不胜感激。使用某种互斥量或信号量只是一种规避问题的方法,并没有真正解决问题。

示意图

Controller A <---------
    |                  |
    |                  | repeats every 2-3 secs.
Service B              |
worker method          |
takes 15 - 20 secs. ----

calls DAO-method getData(token)
    |
  do work
    |
calls DAO-method updateData(token)

控制器(A)

@Controller
@RequestMapping("/test")
public class TestController {

    @Autowired
    private TestService testService;
    ...
    ...

    @GetMapping(value="/RunWorker")
    public String runWorker(ModelMap map, HttpServletRequest hsr)  {
        ...
        testService.workerMethod(token);
        ...
    }
}

服务 (B)

public interface TestService {
    public void workerMethod(long token);
}

@Service
public class TestServiceImpl implements TestService {

    @Autowired
    private TestDAO testDao;

    @Override
    public void workerMethod(long token) {
        List<MyData> myDataSet = testDao.getData(token);
        ...
        // very long process
        ...
        testDao.updateData(token);
    }
}

DAO(C)

public interface TestDAO {
    public List<MyData> getData(long token);
    public void updateData(long token);
}

@Service
public class TestDAOImpl implements TestDAO {

    @Autowired
    private TestMapper testMapper;  // using Mybatis mappers

    public List<MyData> getData(long token) {
        return testMapper.getData(token);
    }

    public void updateData(long token) {
        testMapper.updateData(token);
    }
}

映射器class(D)

public interface TestMapper {
    @Select("SELECT * FROM TESTTABLE WHERE TOKEN=#{token}")
    public List<MyData> getData(@Param("token") long token);

    @Update("UPDATE TESTTABLE SET STATUS=9 WHERE TOKEN=#{token}
    public void updateData(@Param("token") long token);
}

谢谢@M。 Deinum 关于@Repository 的建议。然而,这并没有帮助。

我将 Spring 服务 (B) 重新制作为具有原型范围的 Spring bean,并使用 @Lookup 注入它。行为仍然相同。第二次调用后,DAO 方法 getData returns 一个空结果集。非常困惑和沮丧。

我解决了这个问题。可能是由于多次调用Spring服务(B)相同的调用参数导致资源耗尽。我猜语句池耗尽了,活动语句返回的速度不够快,然后每次调用都返回空数据集。

此致,

彼得