A driver operation has been interrupted (mongodb exception) - mongodb-java

I am using mongo database for my application
for connection spooling in configured the below mongoOption while creating connection
MongoOptions options = new MongoOptions();
options.autoConnectRetry = true;
options.connectionsPerHost = 40;
options.threadsAllowedToBlockForConnectionMultiplier = 25;
while exceuting my application,getting the following exception
com.mongodb.MongoInterruptedException: A driver operation has been interrupted
at com.mongodb.DBPortPool.get(DBPortPool.java:216)
at com.mongodb.DBTCPConnector$MyPort.get(DBTCPConnector.java:440)
at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:177)
at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:155)
at com.mongodb.DBApiLayer$MyCollection.update(DBApiLayer.java:349)
at com.mongodb.DBCollection.update(DBCollection.java:177)
at com.mongodb.DBCollection.save(DBCollection.java:817)
at com.mongodb.DBCollection.save(DBCollection.java:785)
at cherrypick.ck.datalayer.mongo.MongoDataAccessLayer.saveObject(MongoDataAccessLayer.java:361)
at cherrypick.ck.emailinterface.CKMailMonitor.processIncomingMessage(CKMailMonitor.java:170)
at cherrypick.ck.emailinterface.CKMailMonitor.monitorNewMessages(CKMailMonitor.java:253)
at cherrypick.ck.emailinterface.CKMailMonitor.run(CKMailMonitor.java:275)
Caused by: java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1325)
at java.util.concurrent.Semaphore.tryAcquire(Semaphore.java:414)
at com.mongodb.util.SimplePool.permitAcquired(SimplePool.java:148)
at com.mongodb.util.SimplePool.get(SimplePool.java:110)
at com.mongodb.DBPortPool.get(DBPortPool.java:214)
could any one can help me to solve the issue.
Thanks in advance
Raja Subramani

I recently faced this exception. This happens if Thread is already interrupted and you are further trying to do some operation on same thread. I handled this exception by clearing the flag by using Thread.interrupted method of java.lang.Thread

I met that problem before, it was caused by the mongo database not your code, so you can enlarge the socket-timeout in your config file or call the dba.

The same error appear when you open multiple mongodb instances. Be sure that are closing the mongo clients before open a new instance. For example:
MongoClient mongo = new MongoClient ("localhost", 27017);
be sure of do:
mongo.close();
I hope it helps

Related

SingleConnectionDataSource now closing on new instance

I have a small commandline utility. My code is simple I create a SingleConnectionDataSource and pass it along till it is needed and I do
ds.getConnection()
Uptil now it was working and I would get a connection and would use it but some months back this stopped working and threw an exception
Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Connection was closed in SingleConnectionDataSource. Check that user code checks should Close() before closing Connections, or set 'suppress Close' to 'true'
Now when i create the datasource I added
((SingleConnectionDataSource)db).setSuppressClose(true);
and now it works fine ( as the exception suggested)
My question is why did it stop working or how was it working before, why would it be closed even at first user. As per the java doc it is supposed to be
Implementation of SmartDataSource that wraps a single JDBC Connection
which is not closed after use.
So I should be the one closing it to begin with at the end of the process.
So technically, I have a question of why did i get the problem that i have already solved but i don't understand when did this start coming.
Edit -- It behaves like this on SQL server only and not Oracle.
Edit2 -- Sorry, In oracle it uses a different way so it works
JdbcTemplate template = new JdbcTemplate(dataSource);
So either use SuppressClose(true) or use JdbcTemplate
We would need to know your database and application server to answer definitively, but my guess is that one or the other was closing the connection after a timeout. Why are you trying to manage the connection to begin with however? Many application servers provide a connection pool.
This is a partial answer to my own question: why would it close the connection before first use?
in SingleConnectionDatasource getConnection calls
/**
* Initialize the underlying Connection via the DriverManager.
*/
public void initConnection() throws SQLException {
if (getUrl() == null) {
throw new IllegalStateException("'url' property is required for lazily initializing a Connection");
}
synchronized (this.connectionMonitor) {
closeConnection();
this.target = getConnectionFromDriver(getUsername(), getPassword());
prepareConnection(this.target);
if (logger.isDebugEnabled()) {
logger.debug("Established shared JDBC Connection: " + this.target);
}
this.connection = (isSuppressClose() ? getCloseSuppressingConnectionProxy(this.target) : this.target);
}
}
This basically, creates a closed connection to begin with. Which makes it more intriguing why did it work in the first place. This class has been with the same initConnection() method since its inception ( as far as I can see on github).

JDBC connection lifecycle for Connection Pool (Hikari) reuse

Hikari: 2.4.7
PostgreSQL JDBC driver: 9.4-1201-jdbc41
I'm trying to understand what must be done to a java.sql.Connection object for it to be available again in the
connection pool?
I've just introduced connection pooling to a multi threaded application that was
previously standing up / tearing down connections with each SQL statement.
What I have noticed, after introducing Hikari, is that as soon as I hit maximumPoolSize every attempt
thereafter to HikariDataSource.getConnection will fail due to connectionTimeout. So it seems like I'm not "releasing" this connection somehow.
The typical use of the Connection object is:
# omits Exception handling, parameter substitution, result evaluation.
PreparedStatement preparedStatement = hikariDataSource.getConnection().prepareStatement(sql);
preparedStatement.executeQuery();
preparedStatement.close();
Is there anything else that is expected to be done on this connection to get it eligible for reuse in the connection pool?
Autocommit is on. Connection.close(), unless doing something special when provided by Hikari, seemed like the exact thing I wanted to avoid.
I don't know Hikari specifically, but for every connection you take out of a connection pool, you have to return that connection when you are done with it.
Typically this is done using Connection.close() - the pool hands out a wrapper function where close() doesn't physically close the connection, only returns it.
So your code should look like this:
Connection con = hikariDataSource.getConnection();
PreparedStatement preparedStatement = con.prepareStatement(sql);
preparedStatement.executeQuery();
preparedStatement.close();
con.close(); // this returns the connection to the pool
Of course the two close() methods should be called in a finally block.

what difference of managed and unmanaged hconnection in hbase?

When i tried to create a HTable instance in this way.
Configuration conf = HBaseConfiguration.create();
HConnection conn = HConnectionManager.getConnection(conf);
conn.getTable("TABLE_NAME");
Then i got a Exception.
#Override
public HTableInterface getTable(TableName tableName, ExecutorService pool) throws IOException {
if (managed) {
throw new IOException("The connection has to be unmanaged.");
}
return new HTable(tableName, this, pool);
}
So , i wants to know the concrete reflection of managed and 'unmanaged' Hconnection?
Before call HConnectionManager.getConnection you have to create connection using HConnectionManager.createConnection passing to it earlier created HBaseConfiguration instance. HConnectionManager.getConnection return connection which is already exists. A bit of HConnectionManager javadoc about how it handle connection pool:
This class has a static Map of HConnection instances keyed by Configuration; all invocations of getConnection(Configuration) that pass the sameConfiguration instance will be returned the sameHConnection instance
In your case, you can simply create connection using HConnectionManager.createConnection and use returned connection to open HTable
Edit:
#ifiddddddbest, I found javadocs for HConnectionImplementation which has description of managed flag(may be it will help you to understand):
#param managed If true, does not do full shutdown on close; i.e.
cleanup of connection to zk and shutdown of all services; we just
close down the resources this connection was responsible for and
decrement usage counters. It is up to the caller to do the full
cleanup. It is set when we want have connection sharing going on --
reuse of zk connection, and cached region locations, established
regionserver connections, etc. When connections are shared, we have
reference counting going on and will only do full cleanup when no more
users of an HConnectionImplementation instance.
In the newer versions of HBase(>1.0), managed flag was disappeared and all connection management now on client side,e.g. client responsible to close it and if it do this, it close all internal connections to ZK,to HBase master, etc, not only decrease reference counter.

Exception caught from before_completion synchronization operation: org.hibernate.SessionException: Session is closed!

I am using Spring with Hibernate Envers to insert record into audit tables. When Wicket application (web) calls service, I see Spring uses OpenSessionViewFiler and sets flushmode to Manual. AuditProcess class the following code in doBeforeTransactionCompletion method:
if (FlushMode.isManualFlushMode(session.getFlushMode())) {
IsManual becomes true, then it uses temporary session to insert record into audit tables. It is working fine.
We have another application EJB, Spring, Hibernate in WebSphere. When we call the same service from EJB, flushmode becomes AUTO and it fails in AuditProcess class in above mentioned method with the error:
"WTRN0074E: Exception caught from before_completion synchronization
operation: org.hibernate.SessionException: Session is closed!"
Please let me know your ideas to resolve this issue:
[4/23/11 17:42:53:582 CDT] 00000023 RegisteredSyn E WTRN0074E: Exception
caught from before_completion synchronization operation:
org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
at org.hibernate.impl.SessionImpl.contains(SessionImpl.java:1739)
at org.hibernate.envers.synchronization.AuditProcess.getCurrentRevisionData(AuditProcess.java:125)
at org.hibernate.envers.synchronization.AuditProcess.executeInSession(AuditProcess.java:104)
at org.hibernate.envers.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:152)
at org.hibernate.engine.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:543)
at org.hibernate.engine.ActionQueue.beforeTransactionCompletion(ActionQueue.java:216)
at org.hibernate.impl.SessionImpl.beforeTransactionCompletion(SessionImpl.java:571)
at org.hibernate.jdbc.JDBCContext.beforeTransactionCompletion(JDBCContext.java:250)
at org.hibernate.transaction.synchronization.CallbackCoordinator.beforeCompletion(CallbackCoordinator.java:125)
at org.hibernate.transaction.synchronization.HibernateSynchronizationImpl.beforeCompletion(HibernateSynchronizationImpl.java:51)
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter$TransactionAdapter$1.invoke(WebSphereExtendedJTATransactionLookup.java:209)
at $Proxy44.beforeCompletion(Unknown Source)
at com.ibm.ws.jtaextensions.SynchronizationCallbackWrapper.beforeCompletion(SynchronizationCallbackWrapper.java:65)
at com.ibm.ws.Transaction.JTA.RegisteredSyncs.distributeBefore(RegisteredSyncs.java:242)
at com.ibm.ws.Transaction.JTA.TransactionImpl.prePrepare(TransactionImpl.java:2408)
at com.ibm.ws.Transaction.JTA.TransactionImpl.stage1CommitProcessing(TransactionImpl.java:1641)
at com.ibm.ws.Transaction.JTA.TransactionImpl.processCommit(TransactionImpl.java:1612)
at com.ibm.ws.Transaction.JTA.TransactionImpl.commit(TransactionImpl.java:1547)
at com.ibm.ws.Transaction.JTA.TranManagerImpl.commit(TranManagerImpl.java:247)
at com.ibm.ws.Transaction.JTA.TranManagerSet.commit(TranManagerSet.java:167)
at com.ibm.ws.uow.UOWManagerImpl.uowCommit(UOWManagerImpl.java:1055)
at com.ibm.ws.uow.UOWManagerImpl.uowEnd(UOWManagerImpl.java:1025)
at com.ibm.ws.uow.UOWManagerImpl.runUnderNewUOW(UOWManagerImpl.java:975)
at com.ibm.ws.uow.UOWManagerImpl.runUnderUOW(UOWManagerImpl.java:509)
at org.springframework.transaction.jta.WebSphereUowTransactionManager.execute(WebSphereUowTransactionManager.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:127)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy66.getAocBufferData(Unknown Source)
at com.cvscaremark.links.submitorder.SubmitOrderFacade.executeSubmitOrderServices(SubmitOrderFacade.java:59)
at com.cvscaremark.links.submitorder.SubmitOrderBean.processSubmitOrder(SubmitOrderBean.java:129)
at com.cvscaremark.links.submitorder.SubmitOrderBean.ejbTimeout(SubmitOrderBean.java:102)
at com.ibm.ejs.container.TimedObjectWrapper.ejbTimeout(TimedObjectWrapper.java:90)
at com.ibm.ejs.container.TimerTaskHandler.doWork(TimerTaskHandler.java:265)
at com.ibm.ws.scheduler.AlarmListener.executeTaskWithNotification(AlarmListener.java:795)
at com.ibm.ws.scheduler.AlarmListener.access$700(AlarmListener.java:120)
at com.ibm.ws.scheduler.AlarmListener$TaskWork.doWork(AlarmListener.java:426)
at com.ibm.ws.scheduler.AlarmListener$TaskWork.run(AlarmListener.java:212)
at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:782)
at com.ibm.ws.asynchbeans.ExecutionContextImpl.go(ExecutionContextImpl.java:85)
at com.ibm.ws.scheduler.AlarmListener.fireTask(AlarmListener.java:1400)
at com.ibm.ws.scheduler.AlarmListener.fired(AlarmListener.java:1318)
at com.ibm.ws.asynchbeans.AlarmImpl.callListenerMethod(AlarmImpl.java:338)
at com.ibm.ws.asynchbeans.timer.GenericTimer.run(GenericTimer.java:216)
at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1150)
at com.ibm.ws.asynchbeans.AlarmImpl.runListenerAsCJWork(AlarmImpl.java:173)
at com.ibm.ws.asynchbeans.am._Alarm.fireAlarm(_Alarm.java:332)
at com.ibm.ws.asynchbeans.am._Alarm.run(_Alarm.java:229)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
Thanks for your help,
Venkat
Haven't mentioned details about session creation.
Session created using getCurrentSession() will return the session that is bound to the currently running thread & gets flushed & closed automatically. If openSession() used, then have to look manually after flush & commit etc.
You can try using one of the following configuration.
In your hibernate.cfg.xml, change the property current_session_context_class to managed.
Can set the flush-mode explicitly as session.setFlushMode(FlushMode.MANUAL).

Is there any way to have the JBoss connection pool reconnect to Oracle when connections go bad?

We have our JBoss and Oracle on separate servers. The connections seem to be dropped and is causing issues with JBoss. How can I have the JBoss reconnect to Oracle if the connection is bad while we figure out why the connections are being dropped in the first place?
Whilst you can use the old "select 1 from dual" trick, the downside with this is that it issues an extra query each and every time you borrow a connection from the pool. For high volumes, this is wasteful.
JBoss provides a special connection validator which should be used for Oracle:
<valid-connection-checker-class-name>
org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>
This makes use of the proprietary ping() method on the Oracle JDBC Connection class, and uses the driver's underlying networking code to determine if the connection is still alive.
However, it's still wasteful to run this each and every time a connection is borrowed, so you may want to use the facility where a background thread checks the connections in the pool, and silently discards the dead ones. This is much more efficient, but means that if the connections do go dead, any attempt to use them before the background thread runs its check will fail.
See the wiki docs for how to configure the background checking (look for background-validation-millis).
There is usually a configuration option on the pool to enable a validation query to be executed on borrow. If the validation query executes successfully, the pool will return that connection. If the query does not execute successfully, the pool will create a new connection.
The JBoss Wiki documents the various attributes of the pool.
<check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>
Seems like it should do the trick.
Not enough rep for a comment, so it's in a form of an answer. The 'Select 1 from dual' and skaffman's org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker method are equivalent , although the connection check does provide a level of abstraction. We had to decompile the oracle jdbc drivers for a troubleshooting exercise and Oracle's internal implementation of the ping is to perform a 'Select 'x' from dual'. Natch.
JBoss provides 2 ways to Validate connection:
- Ping based AND
- Query based
You can use as per requirement. This is scheduled by separate thread as per duration defined in datasource configuration file.
<background-validation>true</background-validation> <background-validation-minutes>1</background-validation-minutes>
Some time if you are not having right oracle driver at Jboss, you may get classcast or related error and for that connection may start dropout from connection pool. You can try creating your own ConnectionValidator class by implementing org.jboss.resource.adapter.jdbc.ValidConnectionChecker interface. This interface provides only single method 'isValidConnection()' and expecting 'NULL' in return for valid connection.
Ex:
public class OracleValidConnectionChecker implements ValidConnectionChecker, Serializable {
private Method ping;
// The timeout (apparently the timeout is ignored?)
private static Object[] params = new Object[] { new Integer(5000) };
public SQLException isValidConnection(Connection c) {
try {
Integer status = (Integer) ping.invoke(c, params);
if (status.intValue() < 0) {
return new SQLException("pingDatabase failed status=" + status);
}
}
catch (Exception e) {
log.warn("Unexpected error in pingDatabase", e);
}
// OK
return null;
}
}
A little update to #skaffman's answer. In JBoss 7 you have to use "class-name" attribute when setting valid connection checker and also package is different:
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker" />
We've recently had some floating request handling failures caused by orphaned oracle DBMS_LOCK session locks that retained indefinitely in client-side connection pool.
So here is a solution that forces session expiry in 30 minutes but doesn't affect application's operation:
<check-valid-connection-sql>select case when 30/60/24 > sysdate-LOGON_TIME then 1 else 1/0 end
from V$SESSION where AUDSID = userenv('SESSIONID')</check-valid-connection-sql>
This may involve some slow down in process of obtaining connections from pool. Make sure to test this under load.

Resources