0

我有一个应用程序可以处理文件中的大量数据并将这些数据放入数据库中。它是单线程的;所以我创建了一个数据库连接,在该连接上创建准备好的语句,然后在处理数据时重用这些语句。我可能会处理数千个文件,并且可以一遍又一遍地重用相同的准备好的语句,但只更新值。这一直工作得很好,但是......

它已经到了处理文件花费太长时间的地步,而且由于它们都是独立的,我想同时处理它们。问题是每个文件可能使用 10 个准备好的语句。所以现在对于每个文件,我正在建立一个新的数据库连接(即使它们是池化的),设置这 10 个准备好的语句,然后关闭它们并关闭每个文件的连接;所以这种情况发生了成千上万次,而不是以前的一次。

我实际上没有做任何计时,但我很好奇这种使用连接和准备好的语句是否是最好的方法?一遍又一遍地设置这些准备好的语句真的很昂贵吗?有一个更好的方法吗?我读到您不想在线程之间共享连接,但也许有一个我没有想到的更好的解决方案?

4

2 回答 2

0

我建议你使用 C3P0 API 检查它 ht​​tp ://www.mchange.com/projects/c3p0/

增强性能是连接和语句池的目的,特别是如果您为每个客户端访问获取非池连接,这是 c3p0 库的主要目标。

这部分取自 C3P0 Doc 关于线程和重负载:

numHelperThreads 和 maxAdministrativeTaskTime 有助于配置 DataSource 线程池的行为。默认情况下,每个 DataSource 只有三个关联的帮助线程。如果性能似乎在重负载下拖累,或者如果您通过 JMX 或直接检查 PooledDataSource 观察到“待处理任务”的数量通常大于零,请尝试增加 numHelperThreads。maxAdministrativeTaskTime 对于遇到无限期挂起的任务和“APPARENT DEADLOCK”消息的用户可能很有用。

此外,我建议您使用 userExecutorExecutorServicein (java.util.concurrent) 来池化您的线程。

如下所示:

Executor executor = Executors.newFixedThreadPool(int numberOfThreadsNeeded);
// Executor executor =Executors.newCachedThreadPool(); // Or this one

executor.execute(runnable);
.
.
.
etc
于 2013-04-23T21:22:32.337 回答
0

如果这种使用连接和准备好的语句是最好的方法?一遍又一遍地设置这些准备好的语句真的很昂贵吗?

您可以肯定地一遍又一遍地重用连接和准备好的语句。您不必重新创建它们,并且对于连接,您当然不必每次都重新连接到数据库服务器。您至少应该使用数据库连接池。此外,您不能同时在多个线程中使用准备好的语句。而且我还认为,对于大多数数据库连接,您不能在不同的线程中使用相同的连接。

也就是说,执行一些分析器运行可能是有意义的,因为线程数据库代码通常提供最小的速度提升,因为您通常受到数据库服务器 IO 而不是线程的限制。如果您混合查询、插入和事务,这可能不是真的。如果您正在与数据库建立远程连接,您可能会获得一些并发性。

为了提高数据库操作的速度,请考虑在大量事务之前关闭自动提交,或者尽可能批量处理您的请求。

于 2013-04-23T21:01:24.563 回答