使用Spring Boot和JdbcNamedTemplate查询数据库时,我遇到连接池耗尽的问题。
它应该如何运作:
截至目前的工作原理:
当我调用端点超过50次(最大池大小)时,我得到此异常:
com.atomikos.jdbc.AtomikosSQLException: Connection pool exhausted - try increasing 'maxPoolSize' and/or 'borrowConnectionTimeout' on the DataSourceBean.
在重新启动应用程序之前,它会保持这样状态。看起来我的DAO或配置有些不足,但我无法弄清楚是什么,尽管整天都在搜索。如果有人可以提供帮助,我将感激不尽。
额外信息: 我没有注意到其他异常。 正确检索所有其他数据。 发送帮助。
更新: 我做了一些实验: 这个应用程序使用了我之前没有提及的另一个dao,因为我忘了。 它的工作方式几乎相同,只是它连接到不同的数据库,所以它有一个单独的配置。它还利用了JdbcNamedTemplate,并使用@Qualifier来选择正确的。
现在,我发现,解雇一个或另一个DAO将不再使用连接。所以问题是:和平共处的是什么?
这是道。
@Component
public class WindowsDao {
private static final String PARAM_1 = "param";
private final String SELECT_ALL = ""
+ " SELECT "
+ " STUFF "
+ " FROM TABLE "
+ " WHERE "
+ " THING =:" + PARAM_1
+ " WITH UR";
@Autowired
private NamedParameterJdbcTemplate myTemplate;
public Optional<List<BottomDealerText>> getWindows(
final WindowsCode windowCode {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue(PARAM_1, windowCode.getValue())
final Optional<List<Window>> windows;
try {
windows = Optional.of(myTemplate.query(
SELECT_ALL,
queryParameters,
new WindowsRowMapper()));
}
catch (final EmptyResultDataAccessException e) {
LOG.warn("No results were found.");
return Optional.empty();
}
return windows;
}
}
从此服务调用DAO:
@Service
@Transactional
public class WindowsService {
@Autowired
private WindowsDao windowsDao;
public Optional<List<Stuff>> getWindows(
final WindowCode windowCode) {
final Optional<List<Window>> windows = windowsDao.getWindows(
windowCode;
return windows;
}
}
从此服务中调用:
@Service
@Transactional
public class AssembleHouseService {
// some things
@Autowired
private WindowsService windowsService;
public House buildHouse(final SomeParams params) {
// This service will fetch parts of the house
HouseBuilder builder = House.builder();
// call other services and then...
builder.windows(windowsService.getWindows(args).orElse(/*something*/));
//and then some more things...
}
}
这是我用来配置数据源的原因:
myDb:
driver: db2
schema: STUFF
unique-resource-name: STUFF
database-name: STUFF1
server-name: myServer
port: 12312
username: hello
password: world
driver-type: 4
min-pool-size: 2
max-pool-size: 50
的RowMapper:
public class WindowsRowMapper implements RowMapper<Window> {
@Override
public Windows mapRow(final ResultSet rs, final int rowNum)
throws SQLException {
return new BottomDealerText(
re.getString("WSIZE"),
rs.getString("DESCRIPTION"),
rs.getString("COLOR"));
}
}
答案 0 :(得分:1)
如果您在同一个事务中有两个只读DAO,那么您可能遇到了Atomikos开源版本中的已知错误,该错误仅在此特定情况下显示。
它已在商业版中修复,但尚未在开源中修复。
希望有所帮助
答案 1 :(得分:0)
只需在这里发布寻找解决方法的人:
如果你不能改变为不同版本的atomikos(或者只是放弃它),对我有用的是添加
Propagation.REQUIRES_NEW
使用这些不同数据源的服务,因此它将是:
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
似乎将这两个读操作放入单独的事务中会使atomikos关闭事务并正确释放连接。