微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 OutOfMemory 之后违反 Oracle 协议

如何解决在 OutOfMemory 之后违反 Oracle 协议

我的一个批处理作业(处理起来真的很繁重)抛出异常和日志。

老实说,如果由内存问题引起的协议违反反之亦然,我在某些时候会迷失方向。

2021-05-08 13:55:52,190 ERROR TransactionAspectSupport - Application exception overridden by rollback exception
java.lang.OutOfMemoryError: Java heap space
        at oracle.jdbc.driver.T4CBlobAccessor.checkAndAllocateLobPrefetchMemory(T4CBlobAccessor.java:319)
        at oracle.jdbc.driver.T4CBlobAccessor.handlePrefetch(T4CBlobAccessor.java:504)
        at oracle.jdbc.driver.T4CBlobAccessor.unmarshalOneRow(T4CBlobAccessor.java:191)
        at oracle.jdbc.driver.T4CTTIrxd.unmarshal(T4CTTIrxd.java:934)
        at oracle.jdbc.driver.T4CTTIrxd.unmarshal(T4CTTIrxd.java:853)
        at oracle.jdbc.driver.T4C8Oall.readRXD(T4C8Oall.java:699)
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:337)
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
        at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
        at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1010)
        at oracle.jdbc.driver.OracleStatement.executeMaybedescribe(OracleStatement.java:1185)
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1275)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576)
        at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3620)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1491)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
        at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
        at org.hibernate.loader.Loader.doQuery(Loader.java:802)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
        at org.hibernate.loader.Loader.doList(Loader.java:2542)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
        at org.hibernate.loader.Loader.list(Loader.java:2271)
        at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
        at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
        at org.hibernate.impl.Criteriaimpl.list(Criteriaimpl.java:347)
        at com.***.property.dao.hibernate.CompanySystemPropertyHibernateDao.retrieveCompanySystemProperty(CompanySystemPropertyHibernateDao.java:107)
        at sun.reflect.GeneratedMethodAccessor574.invoke(UnkNown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
2021-05-08 14:05:46,590 ERROR TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task.
org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: JDBC rollback Failed
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:680)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:846)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:823)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:493)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:264)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at com.sun.proxy.$Proxy68.refresh(UnkNown Source)
        at sun.reflect.GeneratedMethodAccessor571.invoke(UnkNown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:64)
        at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:53)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
Caused by: org.hibernate.TransactionException: JDBC rollback Failed
        at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:200)
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:677)
        ... 20 more
Caused by: java.sql.sqlException: Protocol violation
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:459)
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
        at oracle.jdbc.driver.T4C7Ocommoncall.doOROLLBACK(T4C7Ocommoncall.java:68)
        at oracle.jdbc.driver.T4CConnection.doRollback(T4CConnection.java:649)
        at oracle.jdbc.driver.PhysicalConnection.rollback(PhysicalConnection.java:3893)
        at com.mchange.v2.c3p0.impl.NewProxyConnection.rollback(NewProxyConnection.java:855)
        at org.hibernate.transaction.JDBCTransaction.rollbackAndResetAutoCommit(JDBCTransaction.java:213)
        at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:192)
        ... 21 more

解决方法

如果有多个 LOB 列和较大的提取大小,则可能在 LOB 预取期间发生这种情况。

使用 LOB 预取,出于性能原因,服务器将数据与 LOB 定位器一起发送。默认情况下,它发送非常 LOB 的前 4k 字节数据。默认情况下,驱动程序还预取行 10 x 10。因此,如果每行有 10 个 LOB,每次“行提取”往返将消耗 10104k,即 400k 字节。当然,这假设每个 LOB 都有超过 4k 字节的数据。

要调整驱动程序并避免此错误,您可以减少默认提取大小或减少 LOB 预取大小。

有一个 JDBC 属性 CONNECTION_PROPERTY_DEFAULT_LOB_PREFETCH_SIZE 来配置不同的 LOB 预取大小。您可以将其设置为“1000”(1k 字节)以减少 LOB 在驱动程序上消耗的内存量。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。