<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=asalant" rel="nofollow">Alon Salant</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-2314?redirect=false" rel="nofollow">SPR-2314</a></strong> and commented</p>
<p dir="auto">AbstractPlatformTransactionManager can get itself in an unrecoverable state when it suspends one transaction and gets an error trying to create a new connection in the same thread of execution. Details and fix follow.</p>
<p dir="auto">The symptom is the exception:</p>
<p dir="auto">java.lang.IllegalStateException: Cannot deactivate transaction synchronization - not active<br>
at org.springframework.transaction.support.TransactionSynchronizationManager.clearSynchronization(TransactionSynchronizationManager.java:263)<br>
at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:746)<br>
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:615)<br>
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:560)<br>
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCloseTransactionAfterThrowing(TransactionAspectSupport.java:285)<br>
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:100)<br>
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)<br>
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)<br>
...</p>
<p dir="auto">When this exception happens the first connection is never closed resulting in abandoned connections in the connection pool. Ouch.</p>
<p dir="auto">To reproduce this error, we have a connection pool with only one connection available. We are using declarative transactions with AOP TransactionInterceptor. methodA() is configured with PROPAGATION_REQUIRED and calls methodB() which is configured with PROPAGATION_REQUIRES_NEW.</p>
<p dir="auto">Calling methodA() results in:</p>
<ol dir="auto">
<li>New connection and transaction for methodA() execution</li>
<li>methodA() calls methodB() resulting in:</li>
<li>AbstractPlatformTransactionManager calls suspend(transaction) at line 321</li>
<li>AbstractPlatformTransactionManager calls doBegin() at line 322 and gets a timeout exception waiting for a new connection</li>
<li>Exception bubbles up causing a rollback but the original transaction is not in place to be rolled back</li>
<li>An exception is thrown in rollback (IllegalStateException) so connection is never closed</li>
</ol>
<p dir="auto">It appears that the fix would be to catch the exception in doBegin() and to resume the original transaction before rethrowing the exception.</p>
<p dir="auto">This patch appears to do it for this specific case. I'm not sure if doBegin() should have the same handling elsewhere:</p>
<p dir="auto">AbstractPlatformTransactionManager.java</p>
<p dir="auto">322c322,330<br>
&lt;                       doBegin(transaction, definition);<br>
—</p>
<blockquote>
<p dir="auto">try<br>
{<br>
doBegin(transaction, definition);<br>
}<br>
catch (RuntimeException e)<br>
{<br>
resume(transaction, (SuspendedResourcesHolder) suspendedResources);<br>
throw e;<br>
}</p>
</blockquote>
<p dir="auto">With this fix, the connection pool timeout exception bubbles all the way up and causes a rollback for the first transaction.</p>
<p dir="auto">Alon</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 1.2.8, 2.0 final</p>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398073023" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/7541" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/7541/hovercard" href="https://github.com/spring-projects/spring-framework/issues/7541">#7541</a> spring should not throw IllegalStateException if begin a transaction fail (<em><strong>"is duplicated by"</strong></em>)</li>
</ul>
<p dir="auto"><strong>Backported to:</strong> <a href="https://github.com/spring-projects/spring-framework/milestone/39?closed=1">1.2.9</a></p>
<p dir="auto">1 votes, 3 watchers</p>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=sbrannen" rel="nofollow">Sam Brannen</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-4072?redirect=false" rel="nofollow">SPR-4072</a></strong> and commented</p>
<p dir="auto">AbstractTestNGSpringContextTests's springTestContextPrepareTestInstance() method is currently annotated with <code class="notranslate">@BeforeClass</code>, which prohibits <code class="notranslate">@BeforeSuite</code> methods in subclasses from interacting with the ApplicationContext.</p>
<p dir="auto">Essentially, the question raised in the forum is: would it be better to annotate the springTestContextPrepareTestInstance() method with <code class="notranslate">@BeforeSuite</code> instead of <code class="notranslate">@BeforeClass</code>?</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 2.5.6, 3.0.7, 3.1.1</p>
<p dir="auto"><strong>Reference URL:</strong> <a href="http://forum.springframework.org/showthread.php?p=148532#post148532" rel="nofollow">http://forum.springframework.org/showthread.php?p=148532#post148532</a></p>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398092680" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/10077" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/10077/hovercard" href="https://github.com/spring-projects/spring-framework/issues/10077">#10077</a> AbstractTestNGSpringContextTests: Spring beans not available within <code class="notranslate">@BeforeTest</code> methods (<em><strong>"is duplicated by"</strong></em>)</li>
</ul>
<p dir="auto">13 votes, 14 watchers</p>