Note that there are some explanatory texts on larger screens.

plurals
  1. POIs there a limit for maximum number of concurrent transactions in Hibernate?
    primarykey
    data
    text
    <p>I've a client that sends 3 requests to a Service Layer which uses Hibernate.</p> <p>Each single request causes Hibernate to begin a transaction (<code>session.beginTransaction()</code>).</p> <p>I find that, <strong>sometimes</strong>, one transaction (from the 2+ running concurrent transactions) fails with <code>createQuery is not valid without active transaction</code>.</p> <p>Here's Hibernate configurations that I use (running in Tomcat 6.0.x and OC4j 10.1.3.4):</p> <pre><code>&lt;property name="hibernate.connection.pool_size"&gt;5&lt;/property&gt; &lt;!-- &lt;property name="hibernate.current_session_context_class"&gt;thread&lt;/property&gt; --&gt; &lt;property name="hibernate.current_session_context_class"&gt;org.hibernate.context.ThreadLocalSessionContext&lt;/property&gt; &lt;property name="connection.autoReconnect"&gt;true&lt;/property&gt; &lt;property name="connection.autoReconnectForPools"&gt;true&lt;/property&gt; &lt;property name="connection.is-connection-validation-required"&gt;true&lt;/property&gt; &lt;property name="hibernate.show_sql"&gt;true&lt;/property&gt; &lt;property name="hibernate.format_sql"&gt;false&lt;/property&gt; &lt;!-- auto commit --&gt; &lt;!-- &lt;property name="connection.autocommit"&gt;true&lt;/property&gt; --&gt; &lt;!-- configuration pool via c3p0 --&gt; &lt;property name="c3p0.idleConnectionTestPeriod"&gt;1000&lt;/property&gt; &lt;property name="c3p0.initialPoolSize"&gt;5&lt;/property&gt; &lt;property name="c3p0.maxPoolSize"&gt;10&lt;/property&gt; &lt;property name="c3p0.maxIdleTime"&gt;1&lt;/property&gt; &lt;property name="c3p0.maxStatements"&gt;30&lt;/property&gt; &lt;property name="c3p0.minPoolSize"&gt;1&lt;/property&gt; &lt;property name="cache.use_query_cache"&gt;true&lt;/property&gt; &lt;property name="cache.provider_class"&gt;org.hibernate.cache.EhCacheProvider&lt;/property&gt; &lt;property name="cache.use_second_level_cache"&gt;true&lt;/property&gt; </code></pre> <p>EDIT: I am using the following Proxy to manage all transactions:</p> <pre><code>import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; /** * http://stackoverflow.com/questions/2587702 * * @author mohammad_abdullah */ public class ServiceProxy implements InvocationHandler { private Object object; private Logger logger = Logger.getLogger(this.getClass().getSimpleName()); private static final String SESSION_FIELD = "session"; public static final Map&lt;Long, Transaction&gt; ACTIVE_TRANSACTIONS = new HashMap&lt;Long, Transaction&gt;(); private ServiceProxy(Object object) { this.object = object; } public static Object newInstance(Object object) { return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new ServiceProxy(object)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; Session session = null; boolean joined = false; try { if (Modifier.isPublic(method.getModifiers())) { session = HibernateUtil.getSessionFactory().getCurrentSession(); Field sessionField = object.getClass().getSuperclass().getDeclaredField(SESSION_FIELD); if (sessionField == null) throw new UPSAdminException("Service Implementation should have field named: \"" + SESSION_FIELD + "\"."); sessionField.setAccessible(true); sessionField.set(object, session); if (session.getTransaction().isActive()) { joined = true; logger.info("Using Already Active transaction" + " Method: " + method.getName() + " Thread: " + Thread.currentThread().getId()); ACTIVE_TRANSACTIONS.put(Thread.currentThread().getId(), session.getTransaction()); } else { logger.info("Transaction Began" + " Method: " + method.getName() + " Thread: " + Thread.currentThread().getId()); Transaction newTnx = session.beginTransaction(); ACTIVE_TRANSACTIONS.put(Thread.currentThread().getId(), newTnx); } result = method.invoke(object, args); if (!joined) { ACTIVE_TRANSACTIONS.get(Thread.currentThread().getId()).commit(); ACTIVE_TRANSACTIONS.remove(Thread.currentThread().getId()); logger.info("Transaction Commited" + " Method: " + method.getName() + " Thread: " + Thread.currentThread().getId()); } } else { result = method.invoke(object, args); } return result; } catch (InvocationTargetException _ex) { Throwable cause = _ex.getCause(); logger.severe("Caller Exception: " + cause + " Method: " + method.getName() + " Thread: " + Thread.currentThread().getId()); if (!joined &amp;&amp; session != null &amp;&amp; session.getTransaction().isActive()) { ACTIVE_TRANSACTIONS.get(Thread.currentThread().getId()).rollback(); ACTIVE_TRANSACTIONS.remove(Thread.currentThread().getId()); } if (cause instanceof HibernateException) { logger.severe("Hibernate Error. Rollbacked Back. Method: " + method.getName() + " Thread: " + Thread.currentThread().getId()); throw new DBException(cause.getCause().getMessage()); } else if (cause instanceof SetRollbackException) { logger.severe("Transaction marked for Rollback. Rollbacked Back. Method: " + method.getName() + " Thread: " + Thread.currentThread().getId()); return result; } else { logger.severe("Error in Business Method : " + method + ". Rollbacked Back." + " Thread: " + Thread.currentThread().getId()); throw cause; } } catch (Exception ex) { logger.severe("Error in Proxy code :" + ex + " Method :" + method + " Thread: " + Thread.currentThread().getId()); if (!joined &amp;&amp; session != null &amp;&amp; session.getTransaction().isActive()) { ACTIVE_TRANSACTIONS.get(Thread.currentThread().getId()).rollback(); ACTIVE_TRANSACTIONS.remove(Thread.currentThread().getId()); } if (ex instanceof HibernateException) throw new DBException(ex.getCause().getMessage()); throw ex; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload