DataNucleus utilises datastore connections as follows
-
PMF : single connection at any one time for datastore-based value generation. Obtained just
for the operation, then released
-
PMF : single connection at any one time for schema-generation. Obtained just for the
operation, then released
-
PM : single connection at any one time. When in a transaction the connection is held
from the point of retrieval until the transaction commits or rolls back; the exact point at
which the connection is obtained is defined more fully below.
When used for non-transactional operations the connection is typically obtained just for the
specific operation (see below).
If you have multiple threads using the same PersistenceManager then you can get "ConnectionInUse"
problems where another operation on another thread comes in and tries to perform something while
that first operation is still in use. This happens because the JDO spec requires an implementation
to use a single datastore connection at any one time. When this situation crops up the user ought
to use multiple PersistenceManagers.
Another important aspect is use of queries for Optimistic transactions, or for non-transactional
contexts. In these situations it isn't possible to keep the datastore connection open indefinitely
and so when the Query is executed the ResultSet is then read into core making the queried objects
available thereafter.
For pessimistic/datastore transactions when
begin()
is called on the transaction,
a connection will be obtained to the datastore. This datastore connection will be held
for the
duration of the transaction
until such time as either
commit()
or
rollback()
are
called.
For optimistic transactions things are a little more complicated. The call to
begin()
has no effect with respect to datastore connections. All updates to the datastore are delayed until
flush() or commit() and so no connection is obtained until that time. When flush() is called, or
the transaction committed a datastore connection is finally obtained and it is held open until
commit/rollback completes. when a datastore operation is required. The connection is typically
released after performing that operation. So datastore connections, in general, are held for much
smaller periods of time.
This is complicated slightly by use of the persistence property
java.jdo.option.IgnoreCache
.
When this is set to
false
, the connection, once obtained, is not released until the call to
commit()/rollback().
When performing non-transactional operations, the default behaviour is to obtain a connection when
needed, and release it after use. With RDBMS you have the option of retaining this connection
ready for the next operation to save the time needed to obtain it; this is enabled by setting the
persistence property
datanucleus.connection.nontx.releaseAfterUse
to
false
.
Sometimes a connection to a datastore can take some time to obtain. For that reason some
datastores can benefit from pooling of connections. Please consult the documentation for the
datastore in use for what is available, in particular for
RDBMS and
LDAP.
JDO defines a mechanism for users to access the native connection to the datastore, so that
they can perform other operations as necessary. You obtain a connection as follows (for RDBMS)
// Obtain the connection from the JDO implementation
JDOConnection conn = pm.getDataStoreConnection();
try
{
java.sql.Connection sqlConn = (java.sql.Connection)conn;
... use the "sqlConn" connection to perform some operations.
}
finally
{
// Hand the connection back to the JDO implementation
conn.close();
}
and for DB4O this would be
// Obtain the connection from the JDO implementation
JDOConnection conn = pm.getDataStoreConnection();
try
{
com.db4o.ObjectContainer objContainer = (com.db4o.ObjectContainer)conn.getNativeConnection();
... use the "objContainer" connection to perform some operations.
}
finally
{
// Hand the connection back to the JDO implementation
conn.close();
}
The "JDOConnection"
in the case of DataNucleus is a wrapper to the native connection for the type of datastore being
used. You now have a connection allowing direct access to the datastore. Things to bear in mind
with this connection
-
You
must
return the connection back to the PersistenceManager before performing any
JDO PM operation. You do this by calling
conn.close()
-
If you don't return the connection and try to perform a JDO PM operation which requires the
connection then a JDOUserException is thrown.