我必须通过Java程序在数据库中注入数据。 我使用Hibernate和Thread(线程池通过Executor),因为客户想要一个快速的软件。 我使用一个线程池。 该程序在45秒 - 1分钟内运行良好,在我出现此错误后,重复并重复:
Exception in thread "pool-1-thread-593" org.hibernate.exception.JDBCConnectionException: Cannot open connection
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:99)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1463)
at fr.msa.agora.bp0gos.qualification.structure.InjecteurFluxStructureRFOSImpl$UnitOfWork.run(InjecteurFluxStructureRFOSImpl.java:107)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.sql.SQLException: socket creation error
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.<init>(Unknown Source)
at org.hsqldb.jdbcDriver.getConnection(Unknown Source)
at org.hsqldb.jdbcDriver.connect(Unknown Source)
at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:294)
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:840)
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:96)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
这是我的代码:
@Service("InjecteurStructure")
public class InjecteurFluxStructureRFOSImpl extends AbstractInjecteurFluxRFOS implements InjecteurFluxRFOS {
private final StructureRFOS2StructureGOSMapperImpl mapper;
@Autowired
public InjecteurFluxStructureRFOSImpl(final StructureRFOS2StructureGOSMapperImpl pMapper,
final SessionFactory pSession, final Executor pPoolDeThread, final GestionRepertoire pGestionRepertoire) {
super(pSession, pPoolDeThread, pGestionRepertoire);
mapper = pMapper;
}
@Override
public void mapUnFichier(final File pFichier) {
final RFOSStructure structureFichier = JAXB.unmarshal(pFichier, RFOSStructure.class);
persisterTable(structureFichier.getSTS());
}
private void persisterTable(final STS pStructureSTS) {
final UnitOfWork unit = new UnitOfWork(mapper, sessionFactory, pStructureSTS);
poolDeThread.execute(unit);
}
private static class UnitOfWork implements Runnable {
private final StructureRFOS2StructureGOSMapperImpl mapper;
private final SessionFactory sessionFactory;
private final STS structureSTS;
public UnitOfWork(final StructureRFOS2StructureGOSMapperImpl pMapper, final SessionFactory pSession,
final STS pStructureSTS) {
mapper = pMapper;
sessionFactory = pSession;
structureSTS = pStructureSTS;
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
final Session session = sessionFactory.openSession();
try {
final fr.msa.agora.bp0gos.metier.sts.domaine.STS structureGOS = mapper.map(structureSTS);
final Transaction transaction = session.beginTransaction();
try {
session.save(structureGOS);
session.flush();
transaction.commit();
} catch (final RuntimeException r) {
transaction.rollback();
throw r;
} catch (final Error error) {
transaction.rollback();
throw error;
}
} finally {
session.close();
}
}
}
}
提前谢谢大家, 托马斯
答案 0 :(得分:1)
我相信你的问题在这里:
此参数包含以下文档:
hibernate.c3p0.max_size这是池中的最大连接数。如果此数字用尽,则会在运行时抛出异常。
显然,如果你有97331个同时连接,你将触发上面提到的异常,我想,正是发生了什么。我建议将ThreadPool
限制为同时只运行20个并发线程。这取决于您的用例。例如,如果您正在运行刚刚启动的那种应用程序,执行此作业然后关闭,那么我建议的方法将正常工作。但是,如果您的应用程序是一个长期运行的应用程序(可能是一个webapp)并且需要从其他用户发生其他数据库连接,那么我建议将ThreadPool max设置得低很多(可能是10),并确保c3p0限制不是&#39;以另一种方式破坏(通过一次连接太多用户,或运行这些工作太多)。提高c3p0限制也会有所帮助。我有一种感觉,没有必要高于100,但我不记得原因,对不起。