Skip to content

Commit 7556a22

Browse files
committed
HHH-9980 - Implement mark-for-rollback-only handling for JdbcResourceLocalTransactionCoordinatorImpl
1 parent f429a8c commit 7556a22

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorImpl.java

+13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.List;
1111
import javax.transaction.Status;
1212

13+
import org.hibernate.TransactionException;
1314
import org.hibernate.engine.jdbc.spi.JdbcServices;
1415
import org.hibernate.engine.transaction.spi.IsolationDelegate;
1516
import org.hibernate.engine.transaction.spi.TransactionObserver;
@@ -185,6 +186,7 @@ public void removeObserver(TransactionObserver observer) {
185186
public class TransactionDriverControlImpl implements TransactionDriver {
186187
private final JdbcResourceTransaction jdbcResourceTransaction;
187188
private boolean invalid;
189+
private boolean rollbackOnly = false;
188190

189191
public TransactionDriverControlImpl(JdbcResourceTransaction jdbcResourceTransaction) {
190192
super();
@@ -211,6 +213,10 @@ protected void errorIfInvalid() {
211213

212214
@Override
213215
public void commit() {
216+
if ( rollbackOnly ) {
217+
throw new TransactionException( "Transaction was marked for rollback only; cannot commit" );
218+
}
219+
214220
JdbcResourceLocalTransactionCoordinatorImpl.this.beforeCompletionCallback();
215221
jdbcResourceTransaction.commit();
216222
JdbcResourceLocalTransactionCoordinatorImpl.this.afterCompletionCallback( true );
@@ -229,7 +235,14 @@ public TransactionStatus getStatus() {
229235

230236
@Override
231237
public void markRollbackOnly() {
238+
if ( log.isDebugEnabled() ) {
239+
log.debug(
240+
"JDBC transaction marked for rollback-only (exception provided for stack trace)",
241+
new Exception( "exception just for purpose of providing stack trace" )
242+
);
243+
}
232244

245+
rollbackOnly = true;
233246
}
234247
}
235248
}

hibernate-core/src/test/java/org/hibernate/test/resource/transaction/jdbc/BasicJdbcTransactionTests.java

+30
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
package org.hibernate.test.resource.transaction.jdbc;
88

9+
import org.hibernate.TransactionException;
910
import org.hibernate.resource.transaction.TransactionCoordinator;
1011
import org.hibernate.resource.transaction.TransactionCoordinatorBuilder;
1112
import org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl;
@@ -50,4 +51,33 @@ public boolean shouldAutoJoinTransaction() {
5051
assertEquals( 0, sync.getFailedCompletionCount() );
5152

5253
}
54+
55+
@Test
56+
@SuppressWarnings("EmptyCatchBlock")
57+
public void testMarkRollbackOnly() {
58+
final TransactionCoordinatorOwnerTestingImpl owner = new TransactionCoordinatorOwnerTestingImpl();
59+
final JdbcResourceLocalTransactionCoordinatorBuilderImpl transactionCoordinatorBuilder =
60+
new JdbcResourceLocalTransactionCoordinatorBuilderImpl();
61+
62+
final TransactionCoordinator transactionCoordinator = transactionCoordinatorBuilder.buildTransactionCoordinator(
63+
owner,
64+
new TransactionCoordinatorBuilder.TransactionCoordinatorOptions() {
65+
@Override
66+
public boolean shouldAutoJoinTransaction() {
67+
return false;
68+
}
69+
}
70+
);
71+
72+
transactionCoordinator.getTransactionDriverControl().begin();
73+
transactionCoordinator.getTransactionDriverControl().markRollbackOnly();
74+
try {
75+
transactionCoordinator.getTransactionDriverControl().commit();
76+
}
77+
catch (TransactionException expected) {
78+
}
79+
finally {
80+
transactionCoordinator.getTransactionDriverControl().rollback();
81+
}
82+
}
5383
}

0 commit comments

Comments
 (0)