blob: ac447453a0d7313298367bf6dd72cfa6fea9e696 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apache TomEE</title>
<meta name="description"
content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." />
<meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" />
<meta name="author" content="Luka Cvetinovic for Codrops" />
<link rel="icon" href="../../../favicon.ico">
<link rel="icon" type="image/png" href="../../../favicon.png">
<meta name="msapplication-TileColor" content="#80287a">
<meta name="theme-color" content="#80287a">
<link rel="stylesheet" type="text/css" href="../../../css/normalize.css">
<link rel="stylesheet" type="text/css" href="../../../css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../../../css/owl.css">
<link rel="stylesheet" type="text/css" href="../../../css/animate.css">
<link rel="stylesheet" type="text/css" href="../../../fonts/font-awesome-4.1.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="../../../fonts/eleganticons/et-icons.css">
<link rel="stylesheet" type="text/css" href="../../../css/jqtree.css">
<link rel="stylesheet" type="text/css" href="../../../css/idea.css">
<link rel="stylesheet" type="text/css" href="../../../css/cardio.css">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2717626-1']);
_gaq.push(['_setDomainName', 'apache.org']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div class="preloader">
<img src="../../../img/loader.gif" alt="Preloader image">
</div>
<nav class="navbar">
<div class="container">
<div class="row"> <div class="col-md-12">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<span>
<img src="../../../img/logo-active.png">
</span>
Apache TomEE
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right main-nav">
<li><a href="../../../docs.html">Documentation</a></li>
<li><a href="../../../community/index.html">Community</a></li>
<li><a href="../../../security/security.html">Security</a></li>
<li><a href="../../../download-ng.html">Downloads</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div></div>
</div>
<!-- /.container-fluid -->
</nav>
<div id="main-block" class="container main-block">
<div class="row title">
<div class="col-md-12">
<div class='page-header'>
<h1>@AccessTimeout Annotation</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Antes de ver la anotación <code>@AccessTimeout</code>, es importante ver cuando una llamada puede necesitar "esperar".</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_esperando">Esperando</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_bean_con_estado_stateful_bean">Bean con estado (Stateful Bean)</h3>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
De forma predeterminada, los clientes pueden realizar llamadas concurrentes a un objeto de sesión con estado y el contenedor es requerido para serializar dichas solicitudes concurrentes. El contenedor nunca permite el acceso multi-threaded a una instancia de un bean de sesión con estado. Por este motivo, los metadatos de bloqueo de los método de lectura / escritura (Read/Write), así como el modo de concurrencia administrada por el bean, no son aplicables a los beans de sesión con estado y no deben ser utilizados.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Esto significa que cuando se ejecuta un método <code>foo ()</code> de una instancia de bean con estado (Stateful Bean) y se recibe una segunda solicitud para ese método u otro método, el contenedor EJB serializaría la segunda solicitud. No permitiría que el método se ejecute concurrentemente, sino esperará hasta que se procese la primera solicitud.</p>
</div>
<div class="paragraph">
<p>El cliente también esperaría cuando un bean anotado con <code>@Stateful</code> está en una transacción y el cliente lo está invocando desde fuera de esa transacción.</p>
</div>
</div>
<div class="sect2">
<h3 id="_bean_sin_estado_stateless_bean">Bean sin estado (Stateless Bean)</h3>
<div class="paragraph">
<p>Si hay 20 instancias de un bean en la la pila (pool) y todas están ocupadas. Cuando llegue la próxima solicitud, el procesamiento <strong>podría esperar</strong> a que un bean esté disponible en la pila. (Nota: la semántica de la pila, si existe, no está cubierta por la especificación. La semántica de pila del proveedor puede o no implicar una condición de espera)</p>
</div>
</div>
<div class="sect2">
<h3 id="_singleton_bean">Singleton Bean</h3>
<div class="paragraph">
<p>El contenedor impone un acceso de un solo hilo (single-threaded) por defecto a los beans de tipo singleton. Eso es el equivalente de anotar con <code>@Lock (Write)</code>. Entonces, cuando se ejecuta un método <code>@Lock (Write)</code>, todas las demás invocaciones de los métodos <code>@Lock (READ)</code> y <code>@Lock (WRITE)</code> tendrán que esperar.</p>
</div>
</div>
<div class="sect2">
<h3 id="_resumen">Resumen</h3>
<div class="ulist">
<ul>
<li>
<p><code>@Singleton</code> - se invoca un método <code>@Lock (WRITE)</code> y se usa la concurrencia administrada por el contenedor. Todos los métodos son <code>@Lock (WRITE)</code> por defecto.</p>
</li>
<li>
<p><code>@Stateful</code>: se invoca cualquier método de la instancia y se produce una segunda invocación. O el bean <code>@Stateful</code> está en una transacción y la llamada es invocada desde fuera de esa transacción.</p>
</li>
<li>
<p><code>@Stateless</code> - no hay instancias disponibles en la pila. Sin embargo, como se señaló, la semática de pila, si corresponde, no está cubierta por la especificación. Si la semántica de agrupación del proveedor implica una condición de espera, se debe aplicar @AccessTimeout.</p>
</li>
</ul>
</div>
</div>
</div>
</div>
<h1 id="__accesstimeout" class="sect0">@AccessTimeout</h1>
<div class="paragraph">
<p><code>@AccessTimeout</code> es simplemente un envoltorio de conveniencia alrededor de las tuplas <code>long</code> y <code>TimeUnit</code> comúnmente usadas en la API <code>java.util.concurrent</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import java.util.concurrent.TimeUnit;
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface AccessTimeout {
long value();
TimeUnit unit() default TimeUnit.MILLISECONDS;
}</code></pre>
</div>
</div>
<div class="sect1">
<h2 id="_uso">Uso</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Un método o clase se puede anotar con <code>@AccessTimeout</code> para especificar el tiempo máximo que una llamada puede esperar para acceder al bean si se produce una condición de espera.</p>
</div>
<div class="paragraph">
<p>La semántica del elemento de valor (value) es la siguiente:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Si <code>value</code> &gt; 0 indica un valor de tiempo de espera en las unidades especificadas por el elemento <code>unit</code>.</p>
</li>
<li>
<p>Si <code>value</code> es 0 significa que el acceso concurrente no está permitido.</p>
</li>
<li>
<p>Si <code>value</code> es -1 indica que la solicitud del cliente se bloqueará indefinidamente hasta que pueda continuar el progreso.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Tan simple como eso!</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
¿Qué excepción recibiría el cliente, con un timeout?
Citando la especificación, "si un método de negocios invocado por el cliente está en progreso en una instancia cuando otra llamada invocada por el cliente, del mismo o diferente cliente, llega a la misma instancia de un bean de sesión con estado, si el segundo cliente es un cliente de la interfaz de negocios del bean o vista sin interfaz, la invocación concurrente debe dar como resultado que el segundo cliente reciba una excepción javax.ejb.ConcurrentAccessException[15]. Si se utiliza la vista de cliente EJB 2.1, el contenedor debe lanzar una excepción java.rmi.RemoteException si el segundo cliente es un cliente remoto o una javax.ejb.EJBException si el segundo cliente es un cliente local"
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="_no_estándar_predeterminado">No estándar predeterminado</h3>
<div class="paragraph">
<p>Notese que el atributo <code>value</code> no tiene valor predeterminado. Esto fue intencional y estaba destinado a comunicar que si <code>@AccessTimeout</code> no se usa explícitamente, el comportamiento que se obtiene es específico del proveedor.</p>
</div>
<div class="paragraph">
<p>Algunos proveedores esperarán un tiempo preconfigurado y lanzarán una excepción <code>javax.ejb.ConcurrentAccessException</code>, algunos proveedores la lanzarán de inmediato.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_ejemplo">Ejemplo</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Aquí tenemos un bean sensillo de tipo @Singleton que tiene tres métodos síncronos y un método asíncrono (<code>@Asynchronous</code>) . El bean en sí está anotado con <code>@Lock (WRITE)</code> para que solo un hilo pueda acceder al <code>@Singleton</code> a la vez. Este es el comportamiento predeterminado de un bean <code>@Singleton</code>, por lo que no es necesario el uso explícito de la anotación <code>@Lock (WRITE)</code>, pero es bastante bueno para mayor claridad ya que la naturaleza de un solo hilo del bean es importante para el ejemplo.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@Singleton
@Lock(WRITE)
public class BusyBee {
@Asynchronous
public Future stayBusy(CountDownLatch ready) {
ready.countDown();
try {
new CountDownLatch(1).await();
} catch (InterruptedException e) {
Thread.interrupted();
}
return null;
}
@AccessTimeout(0)
public void doItNow() {
// do something
}
@AccessTimeout(value = 5, unit = TimeUnit.SECONDS)
public void doItSoon() {
// do something
}
@AccessTimeout(-1)
public void justDoIt() {
// do something
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>El método <code>@Asynchronous</code> no es una parte crítica de <code>@AccessTimeout</code>, pero sirve como una forma simple de "bloquear" el bean para propósitos de prueba. Nos permite probar fácilmente el comportamiento concurrente del bean.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public class BusyBeeTest extends TestCase {
public void test() throws Exception {
final Context context = EJBContainer.createEJBContainer().getContext();
final CountDownLatch ready = new CountDownLatch(1);
final BusyBee busyBee = (BusyBee) context.lookup("java:global/access-timeout/BusyBee");
// This asynchronous method will never exit
busyBee.stayBusy(ready);
// Are you working yet little bee?
ready.await();
// OK, Bee is busy
{ // Timeout Immediately
final long start = System.nanoTime();
try {
busyBee.doItNow();
fail("The bee should be busy");
} catch (Exception e) {
// the bee is still too busy as expected
}
assertEquals(0, seconds(start));
}
{ // Timeout in 5 seconds
final long start = System.nanoTime();
try {
busyBee.doItSoon();
fail("The bee should be busy");
} catch (Exception e) {
// the bee is still too busy as expected
}
assertEquals(5, seconds(start));
}
// This will wait forever, give it a try if you have that long
//busyBee.justDoIt();
}
private long seconds(long start) {
return TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_ejecución">Ejecución</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">mvn clean test</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_salida_de_la_terminal">Salida de la terminal</h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.superbiz.accesstimeout.BusyBeeTest
Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06
http://tomee.apache.org/
INFO - openejb.home = /Users/dblevins/examples/access-timeout
INFO - openejb.base = /Users/dblevins/examples/access-timeout
INFO - Using 'javax.ejb.embeddable.EJBContainer=true'
INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
INFO - Found EjbModule in classpath: /Users/dblevins/examples/access-timeout/target/classes
INFO - Beginning load: /Users/dblevins/examples/access-timeout/target/classes
INFO - Configuring enterprise application: /Users/dblevins/examples/access-timeout
INFO - Configuring Service(id=Default Singleton Container, type=Container, provider-id=Default Singleton Container)
INFO - Auto-creating a container for bean BusyBee: Container(type=SINGLETON, id=Default Singleton Container)
INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container)
INFO - Auto-creating a container for bean org.superbiz.accesstimeout.BusyBeeTest: Container(type=MANAGED, id=Default Managed Container)
INFO - Enterprise application "/Users/dblevins/examples/access-timeout" loaded.
INFO - Assembling app: /Users/dblevins/examples/access-timeout
INFO - Jndi(name="java:global/access-timeout/BusyBee!org.superbiz.accesstimeout.BusyBee")
INFO - Jndi(name="java:global/access-timeout/BusyBee")
INFO - Jndi(name="java:global/EjbModule748454644/org.superbiz.accesstimeout.BusyBeeTest!org.superbiz.accesstimeout.BusyBeeTest")
INFO - Jndi(name="java:global/EjbModule748454644/org.superbiz.accesstimeout.BusyBeeTest")
INFO - Created Ejb(deployment-id=org.superbiz.accesstimeout.BusyBeeTest, ejb-name=org.superbiz.accesstimeout.BusyBeeTest, container=Default Managed Container)
INFO - Created Ejb(deployment-id=BusyBee, ejb-name=BusyBee, container=Default Singleton Container)
INFO - Started Ejb(deployment-id=org.superbiz.accesstimeout.BusyBeeTest, ejb-name=org.superbiz.accesstimeout.BusyBeeTest, container=Default Managed Container)
INFO - Started Ejb(deployment-id=BusyBee, ejb-name=BusyBee, container=Default Singleton Container)
INFO - Deployed Application(path=/Users/dblevins/examples/access-timeout)
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 6.071 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-6 text-center-mobile">
<h3 class="white">Be simple. Be certified. Be Tomcat.</h3>
<h5 class="light regular light-white">"A good application in a good server"</h5>
<ul class="social-footer">
<li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li>
<li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li>
<li><a href="https://plus.google.com/communities/105208241852045684449"><i class="fa fa-google-plus"></i></a></li>
</ul>
</div>
<div class="col-sm-6 text-center-mobile">
<div class="row opening-hours">
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../latest/docs/" class="white">Documentation</a></h5>
<ul class="list-unstyled">
<li><a href="../../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li>
<li><a href="../../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li>
<li><a href="../../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li>
<li><a href="../../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../latest/examples/" class="white">Examples</a></h5>
<ul class="list-unstyled">
<li><a href="../../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li>
<li><a href="../../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li>
<li><a href="../../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li>
<li><a href="../../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../community/index.html" class="white">Community</a></h5>
<ul class="list-unstyled">
<li><a href="../../../community/contributors.html" class="regular light-white">Contributors</a></li>
<li><a href="../../../community/social.html" class="regular light-white">Social</a></li>
<li><a href="../../../community/sources.html" class="regular light-white">Sources</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../security/index.html" class="white">Security</a></h5>
<ul class="list-unstyled">
<li><a href="http://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li>
<li><a href="http://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li>
<li><a href="http://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row bottom-footer text-center-mobile">
<div class="col-sm-12 light-white">
<p>Copyright &copy; 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
</div>
</div>
</div>
</footer>
<!-- Holder for mobile navigation -->
<div class="mobile-nav">
<ul>
<li><a hef="../../../latest/docs/admin/index.html">Administrators</a>
<li><a hef="../../../latest/docs/developer/index.html">Developers</a>
<li><a hef="../../../latest/docs/advanced/index.html">Advanced</a>
<li><a hef="../../../community/index.html">Community</a>
</ul>
<a href="#" class="close-link"><i class="arrow_up"></i></a>
</div>
<!-- Scripts -->
<script src="../../../js/jquery-1.11.1.min.js"></script>
<script src="../../../js/owl.carousel.min.js"></script>
<script src="../../../js/bootstrap.min.js"></script>
<script src="../../../js/wow.min.js"></script>
<script src="../../../js/typewriter.js"></script>
<script src="../../../js/jquery.onepagenav.js"></script>
<script src="../../../js/tree.jquery.js"></script>
<script src="../../../js/highlight.pack.js"></script>
<script src="../../../js/main.js"></script>
</body>
</html>