多次重复调用 DAO 后返回空数据集
Empty data set returned after a few repeated calls to DAO
我遇到了一个严重的问题,DAO 层在几次调用后停止返回记录。我正在使用 Spring Framework 5.3.10。涉及的主要组件是:
- Spring HikariCP 5.0.0 上的 MVC 连接池
- JDBC 连接器 Jaybird 4.0.3(Firebird 3.0.7 数据库服务器)
- ThreadPoolExecutor(使用默认值)
- Spring 交易
- Mybatis
我有一个 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)相同的调用参数导致资源耗尽。我猜语句池耗尽了,活动语句返回的速度不够快,然后每次调用都返回空数据集。
此致,
彼得
我遇到了一个严重的问题,DAO 层在几次调用后停止返回记录。我正在使用 Spring Framework 5.3.10。涉及的主要组件是:
- Spring HikariCP 5.0.0 上的 MVC 连接池
- JDBC 连接器 Jaybird 4.0.3(Firebird 3.0.7 数据库服务器)
- ThreadPoolExecutor(使用默认值)
- Spring 交易
- Mybatis
我有一个 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)相同的调用参数导致资源耗尽。我猜语句池耗尽了,活动语句返回的速度不够快,然后每次调用都返回空数据集。
此致,
彼得