ORA-12518,TNS:监听器无法切断客户端连接来自具有大量内存访问的循环

时间:2017-07-16 08:05:00

标签: java oracle

我有一个来自oracle的大量内存访问循环。

    int firstResult = 0;
    int maxResult = 500;
    int targetTotal = 8000; // more or less

    int phase = 1;
    for (int i = 0; i<= targetTotal; i += maxResult) {
        try {
            Session session = .... init hibernate session ...
            // Start Transaction
            List<Accounts> importableInvAcList = ...getting list using session and firstResult-maxResult...

            List<ContractData> dataList = new ArrayList<>();
            List<ErrorData> errorDataList = new ArrayList<>();

            for (Accounts account : importableInvAcList) {
                ... Converting 500 Accounts object to ContractData object ...
                ... along with 5 more database call using existing session ...
                .. On converting The object we generate thousands of ErrorData...

                dataList.add(.. converted account to Contract data ..);
                errorDataList.add(.. generated error data ..);
            }

            dataList.stream().forEach(session::save); // 500 data

            errorDataList.stream().forEach(session::save); // 10,000-5,000 data

            ... Commit Transaction ...
            phase++;
        } catch (Exception e) {

            return;
        }
    }

在第二阶段(第二阶段),Exception出现。有时Exception将在第3阶段或第5阶段出现。

我还检查了运行时内存。

    Runtime runtime = Runtime.getRuntime();
    long total = runtime.totalMemory();
    long free = runtime.freeMemory();
    long used = total - free;
    long max = runtime.maxMemory();

在第二阶段,状态低于样本......

已使用: 1022 MB ,免费: 313 MB ,已分配总数: 1335 MB

Stack Trace就在这里......

    org.hibernate.exception.GenericJDBCException: Cannot open connection
        at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
        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 ibbl.remote.tx.TxSessionImpl.beginTx(TxSessionImpl.java:41)
        at ibbl.remote.tx.TxController.initPersistence(TxController.java:70)
        at com.ibbl.data.util.CDExporter2.run(CDExporter2.java:130)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLException: Listener refused the connection with the following error:
ORA-12518, TNS:listener could not hand off client connection

注意,此过程在Thread中运行,并且一次有3个类似的Thread在运行。 为什么在循环运行一段时间后此异常会挂起?

1 个答案:

答案 0 :(得分:1)

  
    

一次有3个类似的Thread运行。

  

如果您的代码总共创建了3个线程,那么最佳地,您只需要3个Oracle连接。在创建任何线程之前创建所有这些。创建线程,为每个线程分配一个连接,然后启动线程。

但是,很有可能你的代码可能过于积极地在托管它的任何机器上消耗资源。即使您消除了ORA-12518,RDBMS服务器也可能会向南移动#34;通过&#34;向南走,我的意思是如果你的应用程序消耗了太多的资源,那么托管它的机器或托管RDBMS服务器的机器可能会惊慌失措&#34;或同样可怕的东西。