1212import org .hibernate .engine .transaction .spi .TransactionImplementor ;
1313import org .hibernate .internal .AbstractSharedSessionContract ;
1414import org .hibernate .internal .CoreLogging ;
15- import org .hibernate .jpa .spi .JpaCompliance ;
1615import org .hibernate .resource .transaction .spi .TransactionCoordinator ;
1716import org .hibernate .resource .transaction .spi .TransactionStatus ;
1817
@@ -28,7 +27,7 @@ public class TransactionImpl implements TransactionImplementor {
2827 private static final Logger LOG = CoreLogging .logger ( TransactionImpl .class );
2928
3029 private final TransactionCoordinator transactionCoordinator ;
31- private final JpaCompliance jpaCompliance ;
30+ private final boolean jpaCompliance ;
3231 private final AbstractSharedSessionContract session ;
3332
3433 private TransactionDriver transactionDriverControl ;
@@ -37,7 +36,9 @@ public TransactionImpl(
3736 TransactionCoordinator transactionCoordinator ,
3837 AbstractSharedSessionContract session ) {
3938 this .transactionCoordinator = transactionCoordinator ;
40- this .jpaCompliance = session .getFactory ().getSessionFactoryOptions ().getJpaCompliance ();
39+ this .jpaCompliance =
40+ session .getFactory ().getSessionFactoryOptions ().getJpaCompliance ()
41+ .isJpaTransactionComplianceEnabled ();
4142 this .session = session ;
4243
4344 if ( session .isOpen () && transactionCoordinator .isActive () ) {
@@ -47,11 +48,8 @@ public TransactionImpl(
4748 LOG .debug ( "TransactionImpl created on closed Session/EntityManager" );
4849 }
4950
50- if ( LOG .isDebugEnabled () ) {
51- LOG .debugf (
52- "On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == %s" ,
53- jpaCompliance .isJpaTransactionComplianceEnabled ()
54- );
51+ if ( LOG .isDebugEnabled () && jpaCompliance ) {
52+ LOG .debugf ( "TransactionImpl created in JPA compliant mode" );
5553 }
5654 }
5755
@@ -65,78 +63,66 @@ public void begin() {
6563 transactionDriverControl = transactionCoordinator .getTransactionDriverControl ();
6664 }
6765
68- // per-JPA
6966 if ( isActive () ) {
70- if ( jpaCompliance .isJpaTransactionComplianceEnabled ()
71- || !transactionCoordinator .getTransactionCoordinatorBuilder ().isJta () ) {
72- throw new IllegalStateException ( "Transaction already active" );
67+ if ( jpaCompliance ) {
68+ throw new IllegalStateException ( "Transaction already active (in JPA compliant mode)" );
7369 }
74- else {
75- return ;
70+ else if ( ! transactionCoordinator . getTransactionCoordinatorBuilder (). isJta () ) {
71+ throw new IllegalStateException ( "Resource-local transaction already active" ) ;
7672 }
7773 }
78-
79- LOG .debug ( "begin" );
80-
81- this . transactionDriverControl . begin ();
74+ else {
75+ LOG .debug ( "begin transaction " );
76+ transactionDriverControl . begin ();
77+ }
8278 }
8379
8480 @ Override
8581 public void commit () {
82+ // allow MARKED_ROLLBACK to propagate through to transactionDriverControl
83+ // the boolean passed to isActive indicates whether MARKED_ROLLBACK should
84+ // be considered active
8685 if ( !isActive ( true ) ) {
87- // allow MARKED_ROLLBACK to propagate through to transactionDriverControl
88- // the boolean passed to isActive indicates whether MARKED_ROLLBACK should be
89- // considered active
90- //
91- // essentially here we have a transaction that is not active and
92- // has not been marked for rollback only
86+ // we have a transaction that is inactive and has not been marked for rollback only
9387 throw new IllegalStateException ( "Transaction not successfully started" );
9488 }
95-
96- LOG .debug ( "committing" );
97-
98- try {
99- internalGetTransactionDriverControl (). commit ();
100- }
101- catch ( RuntimeException e ) {
102- throw session . getExceptionConverter (). convertCommitException ( e );
89+ else {
90+ LOG .debug ( "committing transaction " );
91+ try {
92+ internalGetTransactionDriverControl (). commit ();
93+ }
94+ catch ( RuntimeException e ) {
95+ throw session . getExceptionConverter (). convertCommitException ( e );
96+ }
10397 }
10498 }
10599
106100 public TransactionDriver internalGetTransactionDriverControl () {
107101 // NOTE here to help be a more descriptive NullPointerException
108- if ( this . transactionDriverControl == null ) {
102+ if ( transactionDriverControl == null ) {
109103 throw new IllegalStateException ( "Transaction was not properly begun/started" );
110104 }
111- return this .transactionDriverControl ;
105+ else {
106+ return transactionDriverControl ;
107+ }
112108 }
113109
114110 @ Override
115111 public void rollback () {
116- if ( !isActive () ) {
117- if ( jpaCompliance .isJpaTransactionComplianceEnabled () ) {
118-
119- throw new IllegalStateException (
120- "JPA compliance dictates throwing IllegalStateException when #rollback " +
121- "is called on non-active transaction"
122- );
123- }
112+ if ( !isActive () && jpaCompliance ) {
113+ throw new IllegalStateException ( "rollback() called on inactive transaction (in JPA compliant mode)" );
124114 }
125115
126- TransactionStatus status = getStatus ();
116+ final TransactionStatus status = getStatus ();
127117 if ( status == TransactionStatus .ROLLED_BACK || status == TransactionStatus .NOT_ACTIVE ) {
128- // Allow rollback() calls on completed transactions, just no-op.
118+ // allow rollback() on completed transaction as noop
129119 LOG .debug ( "rollback() called on an inactive transaction" );
130- return ;
131120 }
132-
133- if ( !status .canRollback () ) {
134- throw new TransactionException ( "Cannot rollback transaction in current status [" + status .name () + "]" );
121+ else if ( !status .canRollback () ) {
122+ throw new TransactionException ( "Cannot roll back transaction in current status [" + status .name () + "]" );
135123 }
136-
137- LOG .debug ( "rolling back" );
138-
139- if ( status != TransactionStatus .FAILED_COMMIT || allowFailedCommitToPhysicallyRollback () ) {
124+ else if ( status != TransactionStatus .FAILED_COMMIT || allowFailedCommitToPhysicallyRollback () ) {
125+ LOG .debug ( "rolling back transaction" );
140126 internalGetTransactionDriverControl ().rollback ();
141127 }
142128 }
@@ -176,55 +162,50 @@ public TransactionStatus getStatus() {
176162
177163 @ Override
178164 public void registerSynchronization (Synchronization synchronization ) throws HibernateException {
179- this . transactionCoordinator .getLocalSynchronizations ().registerSynchronization ( synchronization );
165+ transactionCoordinator .getLocalSynchronizations ().registerSynchronization ( synchronization );
180166 }
181167
182168 @ Override
183169 public void setTimeout (int seconds ) {
184- this . transactionCoordinator .setTimeOut ( seconds );
170+ transactionCoordinator .setTimeOut ( seconds );
185171 }
186172
187173 @ Override
188174 public void setTimeout (@ Nullable Integer seconds ) {
189- this . transactionCoordinator .setTimeOut ( seconds == null ? -1 : seconds );
175+ transactionCoordinator .setTimeOut ( seconds == null ? -1 : seconds );
190176 }
191177
192178 @ Override
193179 public @ Nullable Integer getTimeout () {
194- final int timeOut = this .transactionCoordinator .getTimeOut ();
195- if ( timeOut == -1 ) {
196- return null ;
197- }
198- return timeOut ;
180+ final int timeout = transactionCoordinator .getTimeOut ();
181+ return timeout == -1 ? null : timeout ;
199182 }
200183
201184 @ Override
202185 public void markRollbackOnly () {
203- // this is the Hibernate-specific API, whereas # setRollbackOnly is the
204- // JPA-defined API. In our opinion it is much more user-friendly to
186+ // this is the Hibernate-specific API, whereas setRollbackOnly is the
187+ // JPA-defined API. In our opinion it is much more user-friendly to
205188 // always allow user/integration to indicate that the transaction
206189 // should not be allowed to commit.
207190 //
208- // However.. should only "do something" on an active transaction
209191 if ( isActive () ) {
210192 internalGetTransactionDriverControl ().markRollbackOnly ();
211193 }
194+ // else noop for an inactive transaction
212195 }
213196
214197 @ Override
215198 public void setRollbackOnly () {
216199 if ( !isActive () ) {
217- // Since this is the JPA-defined one, we make sure the txn is active first
218- // so long as compliance (JpaCompliance) has not been defined to disable
219- // that check - making this active more like Hibernate's #markRollbackOnly
220- if ( jpaCompliance .isJpaTransactionComplianceEnabled () ) {
221- throw new IllegalStateException (
222- "JPA compliance dictates throwing IllegalStateException when #setRollbackOnly " +
223- "is called on non-active transaction"
224- );
200+ if ( jpaCompliance ) {
201+ // This is the JPA-defined version of this operation,
202+ // so we must check that the transaction is active
203+ throw new IllegalStateException ( "setRollbackOnly() called on inactive transaction (in JPA compliant mode)" );
225204 }
226205 else {
227- LOG .debug ( "#setRollbackOnly called on a not-active transaction" );
206+ // JpaCompliance disables the check, so this method
207+ // is equivalent our native markRollbackOnly()
208+ LOG .debug ( "setRollbackOnly() called on a inactive transaction" );
228209 }
229210 }
230211 else {
@@ -234,16 +215,12 @@ public void setRollbackOnly() {
234215
235216 @ Override
236217 public boolean getRollbackOnly () {
237- if ( !isActive () ) {
238- if ( jpaCompliance .isJpaTransactionComplianceEnabled () ) {
239- throw new IllegalStateException (
240- "JPA compliance dictates throwing IllegalStateException when #getRollbackOnly " +
241- "is called on non-active transaction"
242- );
243- }
218+ if ( jpaCompliance && !isActive () ) {
219+ throw new IllegalStateException ( "getRollbackOnly() called on inactive transaction (in JPA compliant mode)" );
220+ }
221+ else {
222+ return getStatus () == TransactionStatus .MARKED_ROLLBACK ;
244223 }
245-
246- return getStatus () == TransactionStatus .MARKED_ROLLBACK ;
247224 }
248225
249226 protected boolean allowFailedCommitToPhysicallyRollback () {
0 commit comments