Spring 如何根据tomcat中的线程计算连接池以避免ORA-12519
问题:我发现以下错误 ORA-12519,TNS:未找到适当的服务处理程序 描述: 我想在tomcat中配置线程和连接池,以便在最佳级别使用它们。 我可以配置高吞吐量(最多500-600个线程)吗, 我还有几个servlet将使用具有类似线程的数据库 我正在调用一个servlet在db中插入条目(下面提到的代码),其中有150个线程需要完成任务Spring 如何根据tomcat中的线程计算连接池以避免ORA-12519,spring,performance,tomcat7,connection-pooling,jdbctemplate,Spring,Performance,Tomcat7,Connection Pooling,Jdbctemplate,问题:我发现以下错误 ORA-12519,TNS:未找到适当的服务处理程序 描述: 我想在tomcat中配置线程和连接池,以便在最佳级别使用它们。 我可以配置高吞吐量(最多500-600个线程)吗, 我还有几个servlet将使用具有类似线程的数据库 我正在调用一个servlet在db中插入条目(下面提到的代码),其中有150个线程需要完成任务 static int joblimit = 100000; static int TPS = 150; public sta
static int joblimit = 100000;
static int TPS = 150;
public static void insertMethod()
{
RateLimiter rateLimiter = RateLimiter.create(TPS);
ExecutorService executorService = Executors.newCachedThreadPool();
start = System.currentTimeMillis();
for (int i = 0; i < joblimit; i++) {
rateLimiter.acquire(); // may wait
final int j = i;
executorService.execute(new Runnable() {
@Override
public void run() {
log.info(str);
try {
callInsertURL(j);
} catch (Exception e) {
log.error(e);
}
if (index == joblimit) {
long timeTaken = System.currentTimeMillis() - start;
String oneThreadProcessedInSecs = ""+(float)(1*(timeTaken/60)/joblimit);
log.info(joblimit + " jobs completed in "
+ timeTaken
+ " msec i.e ["+(float)(timeTaken/60)+"sec,"+"] with " + TPS + " tps, oneThreadProcessedInSecs="+oneThreadProcessedInSecs);
}
}
});
}
try {
executorService.shutdown();
executorService.awaitTermination(100, TimeUnit.SECONDS);
log.info("--------------All Tasks Processed Processed----------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
访问数据库的方法:
@Autowired
@Qualifier("commonDAO")
protected CommonDAO commonDAO;
String qry = "INSERT INTO TB_CUSTOMER(customer_msisdn,op_id,cuser,country_id) VALUES(?,?,?,?)";
String[] colNamesTobeReturned = {"CUSTOMER_ID"};
commonDAO.insertOrUpdateWithReturnPK(qry, colNamesTobeReturned, msisdn,opid,cuser,countryid);
public Long insertOrUpdateWithReturnPK(final String qry,final String[] colNamesTobeReturned,final Object... params)
{
KeyHolder keyHolder = new GeneratedKeyHolder();
try {
getJdbcTemplate().update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(qry, colNamesTobeReturned);
utilMapParamsToPStmt(ps,params);
return ps;
}
},
keyHolder);
if(keyHolder != null)
return keyHolder.getKey().longValue();
} catch (Exception e) {
handleDBExceptions(e);
}
return 0L;
}
您的DB方法可以改进,因为您不希望每次需要时都构造一个
JdbcTEmplate
。它是一个非常沉重的对象,您需要创建一次并重用它。您不应该传递数据源
。因为计算池大小是一个有趣的阅读,基本上不要让它太高。@M.Deinum,谢谢你的回复,我只想创建一次像datasource这样的对象,我有下面这样的控制器类,从那里我传递datasource,你想让我创建JdbcTemplate也像这样吗?我可以将同一对象也用于其他控制器吗@Controller公共类CntCustomer extensed BaseController{}公共类BaseController{@Autowired@Qualifier(CommonDAOConstants.JNDI_NAME)受保护的数据源数据源;public void setDataSource(DataSource DataSource){this.DataSource=DataSource;}}
不要在注释中添加代码将其添加到您的问题中。YOUR控制器、DAO等应该是单例(它们不应该保持状态),您还需要只构造一次JdbcTemplate
,在构建之后,它是线程安全的,正如前面提到的,它是一个需要构建的沉重对象,因为它会查找数据库以确定类型等。在控制器中插入数据源是没有意义的,这是一个web东西,不应该知道任何关于它的信息。@M.Deinum,当然,我将相应地修改这个问题。@M.Deinum我已经更改了代码,仍然有60个线程,我也得到了相同的错误。