OPENJPA-160

git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@512906 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Patrick Linskey 2007-02-28 19:20:51 +00:00
parent 31010aa2ac
commit 560f895102
7 changed files with 157 additions and 33 deletions

View File

@ -0,0 +1,49 @@
package org.apache.openjpa.conf;
import org.apache.openjpa.lib.conf.PluginValue;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.kernel.BrokerImpl;
import org.apache.openjpa.kernel.FinalizingBrokerImpl;
import org.apache.openjpa.util.InternalException;
/**
* Custom {@link PluginValue} that can efficiently create {@link BrokerImpl}
* instances.
*
* @since 0.9.7
*/
public class BrokerValue
extends PluginValue {
private BrokerImpl _templateBroker;
public BrokerValue(String prop) {
super(prop, false);
String[] aliases = new String[] {
"default", FinalizingBrokerImpl.class.getName(),
"non-finalizing", BrokerImpl.class.getName(),
};
setAliases(aliases);
setDefault(aliases[0]);
setString(aliases[0]);
}
public Object newInstance(String clsName, Class type, Configuration conf,
boolean fatal) {
if (BrokerImpl.class.getName().equals(clsName)) {
// This is not synchronized. If there are concurrent invocations
// while _templateBroker is null, we'll just end up with extra
// template brokers, which will get safely garbage collected.
if (_templateBroker == null)
_templateBroker = (BrokerImpl) super.newInstance(
clsName, type, conf, fatal);
try {
return _templateBroker.clone();
} catch (CloneNotSupportedException e) {
throw new InternalException(e);
}
} else {
return super.newInstance(clsName, type, conf, fatal);
}
}
}

View File

@ -71,7 +71,7 @@ public class OpenJPAConfigurationImpl
// openjpa properties
public ObjectValue classResolverPlugin;
public ObjectValue brokerPlugin;
public BrokerValue brokerPlugin;
public ObjectValue dataCachePlugin;
public ObjectValue dataCacheManagerPlugin;
public IntValue dataCacheTimeout;
@ -178,11 +178,8 @@ public class OpenJPAConfigurationImpl
brokerFactoryPlugin = new BrokerFactoryValue();
addValue(brokerFactoryPlugin);
brokerPlugin = addPlugin("BrokerImpl", false);
aliases = new String[] { "default", BrokerImpl.class.getName() };
brokerPlugin.setAliases(aliases);
brokerPlugin.setDefault(aliases[0]);
brokerPlugin.setString(aliases[0]);
brokerPlugin = new BrokerValue("BrokerImpl");
addValue(brokerPlugin);
dataCacheManagerPlugin = addPlugin("DataCacheManager", true);
aliases =

View File

@ -96,7 +96,7 @@ import org.apache.openjpa.util.UserException;
* @author Abe White
*/
public class BrokerImpl
implements Broker, FindCallbacks {
implements Broker, FindCallbacks, Cloneable {
/**
* Incremental flush.
@ -155,14 +155,13 @@ public class BrokerImpl
private ManagedRuntime _runtime = null;
private LockManager _lm = null;
private InverseManager _im = null;
private final JCAHelper _jca = new JCAHelper();
private JCAHelper _jca = null;
private ReentrantLock _lock = null;
private OpCallbacks _call = null;
private RuntimeExceptionTranslator _extrans = null;
// cache class loader associated with the broker
private ClassLoader _loader = Thread.currentThread().
getContextClassLoader();
private ClassLoader _loader = null;
// user state
private Synchronization _sync = null;
@ -225,6 +224,8 @@ public class BrokerImpl
private LifecycleEventManager _lifeEventManager = null;
private int _lifeCallbackMode = 0;
private boolean _initializeWasInvoked = false;
/**
* Set the persistence manager's authentication. This is the first
* method called after construction.
@ -251,6 +252,9 @@ public class BrokerImpl
*/
public void initialize(AbstractBrokerFactory factory,
DelegatingStoreManager sm, boolean managed, int connMode) {
_initializeWasInvoked = true;
_loader = Thread.currentThread().getContextClassLoader();
_jca = new JCAHelper();
_conf = factory.getConfiguration();
_compat = _conf.getCompatibilityInstance();
_factory = factory;
@ -295,14 +299,13 @@ public class BrokerImpl
beginInternal();
}
/**
* Close on finalize.
*/
protected void finalize()
throws Throwable {
super.finalize();
if (!isClosed())
free();
public Object clone()
throws CloneNotSupportedException {
if (_initializeWasInvoked)
throw new CloneNotSupportedException();
else {
return super.clone();
}
}
/**

View File

@ -0,0 +1,23 @@
package org.apache.openjpa.kernel;
/**
* Subtype of {@link BrokerImpl} that automatically closes itself during
* finalization. This implementation guards against potential resource leaks,
* but also incurs a scalability bottleneck as instances are enlisted in the
* finalization queue and subsequently cleaned up.
*
* @since 0.9.7
*/
public class FinalizingBrokerImpl
extends BrokerImpl {
/**
* Close on finalize.
*/
protected void finalize()
throws Throwable {
super.finalize();
if (!isClosed())
free();
}
}

View File

@ -585,7 +585,7 @@ BrokerImpl</literal>
<xref linkend="ref_guide_conf_plugins"/>) describing the
<ulink url="../javadoc/org/apache/openjpa/kernel/Broker.html"><classname>
org.apache.openjpa.kernel.Broker</classname></ulink> type to use at runtime. See
<xref linkend="ref_guide_runtime_pmextension"/> on for details.
<xref linkend="ref_guide_runtime_broker_extension"/> on for details.
</para>
</section>
<section id="openjpa.ClassResolver">

View File

@ -564,6 +564,25 @@ loading subclass data or traversing relations for each instance in a large
collection of results can speed up data loading by orders of magnitude.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Disable BrokerImpl finalization
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
By default, OpenJPA's EntityManagers use finalizers to ensure that resources
get cleaned up. If you are properly managing your resources, this finalization
is not necessary, and will introduce unneeded synchronization, leading to
scalability problems. You can disable this protective behavior by setting the
<literal>openjpa.BrokerImpl</literal> property to
<literal>non-finalizing</literal>. See <link
linkend="ref_guide_runtime_broker_finalization"/> for details.
</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -103,11 +103,37 @@ allows you to convert between <classname>EntityManagerFactories</classname> and
<classname>BrokerFactories</classname>, <classname>EntityManager</classname>s
and <classname>Broker</classname>s.
</para>
<section id="ref_guide_runtime_pmextension">
<section id="ref_guide_runtime_broker_finalization">
<title>
Broker Customization
Broker Finalization
</title>
<indexterm zone="ref_guide_runtime_pmextension">
<indexterm zone="ref_guide_runtime_broker_finalization">
<primary>
EntityManager
</primary>
<secondary>
finalizing
</secondary>
<secondary>
clean-up
</secondary>
</indexterm>
<para>
The default OpenJPAEntityManager implementation automatically closes itself
during instance finalization. This guards against accidental resource leaks
that may occur if a developer fails to explicitly close EntityManagers when
finished with them, but it also incurs a scalability bottleneck, since the
JVM must perform synchronization during instance creation, and since the
finalizer thread will have more instances to monitor. To avoid this overhead,
set the <link linkend="openjpa.BrokerImpl"><literal>openjpa.BrokerImpl</literal>
</link> configuration property to <literal>non-finalizing</literal>.
</para>
</section>
<section id="ref_guide_runtime_broker_extension">
<title>
Broker Customization and Finalization
</title>
<indexterm zone="ref_guide_runtime_broker_extension">
<primary>
OpenJPAEntityManager
</primary>
@ -116,17 +142,8 @@ and <classname>Broker</classname>s.
</secondary>
</indexterm>
<para>
Some advanced users may want to add capabilities to OpenJPA's internal
<ulink url="../javadoc/org/apache/openjpa/kernel/BrokerImpl.html"><classname>
org.apache.openjpa.kernel.BrokerImpl</classname></ulink>. You can configure
OpenJPA to use a custom subclass of <classname>BrokerImpl</classname> through
the <link linkend="openjpa.BrokerImpl"><literal>openjpa.BrokerImpl</literal>
</link> configuration property. Set this property to the full class name of your
custom subclass.
</para>
<para>
As a <link linkend="ref_guide_conf_plugins">plugin string</link>, you can also
use this property to configure the <classname> BrokerImpl</classname> with the
As a <link linkend="ref_guide_conf_plugins">plugin string</link>, this property
can be used to configure the <classname> BrokerImpl</classname> with the
following properties:
</para>
<itemizedlist>
@ -147,6 +164,22 @@ Defaults to <literal>false</literal>.
&lt;property name="openjpa.BrokerImpl" value="EvictFromDataCache=true"/&gt;
</programlisting>
</example>
<para>
Additionally, some advanced users may want to add capabilities to OpenJPA's
internal <ulink url="../javadoc/org/apache/openjpa/kernel/BrokerImpl.html">
<classname>org.apache.openjpa.kernel.BrokerImpl</classname></ulink>. You can
configure OpenJPA to use a custom subclass of <classname>BrokerImpl</classname>
with the <link linkend="openjpa.BrokerImpl"><literal>openjpa.BrokerImpl
</literal></link> configuration property. Set this property to the full class
name of your custom subclass. When implementing your subclass, consider the
finalization issues mentioned in
<link linkend="ref_guide_runtime_broker_finalization"/>. It may be appropriate
to create a subtype of both
<ulink url="../javadoc/org/apache/openjpa/kernel/BrokerImpl.html">
<classname>org.apache.openjpa.kernel.BrokerImpl</classname></ulink> and
<ulink url="../javadoc/org/apache/openjpa/kernel/FinalizingBrokerImpl.html">
<classname>org.apache.openjpa.kernel.FinalizingBrokerImpl</classname></ulink>.
</para>
</section>
</section>
<section id="ref_guide_runtime_jpa">