Skip to content

Commit fcbc7fc

Browse files
authored
Merge pull request #622 from zhenlineo/4.0-commit-rollback
`Transaction#commit` and `Transaction#rollback`
2 parents 58aa548 + 83d57d7 commit fcbc7fc

32 files changed

+457
-516
lines changed

driver/src/main/java/org/neo4j/driver/Session.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ public interface Session extends Resource, StatementRunner
8888
/**
8989
* Execute given unit of work in a {@link AccessMode#READ read} transaction.
9090
* <p>
91-
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or from
92-
* {@link Transaction#close()} or transaction is explicitly marked for failure via {@link Transaction#failure()}.
91+
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or during committing,
92+
* or transaction is explicitly committed via {@link Transaction#commit()} or rolled back via {@link Transaction#rollback()}.
9393
*
9494
* @param work the {@link TransactionWork} to be applied to a new read transaction.
9595
* @param <T> the return type of the given unit of work.
@@ -100,8 +100,8 @@ public interface Session extends Resource, StatementRunner
100100
/**
101101
* Execute given unit of work in a {@link AccessMode#READ read} transaction with the specified {@link TransactionConfig configuration}.
102102
* <p>
103-
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or from
104-
* {@link Transaction#close()} or transaction is explicitly marked for failure via {@link Transaction#failure()}.
103+
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or during committing,
104+
* or transaction is explicitly committed via {@link Transaction#commit()} or rolled back via {@link Transaction#rollback()}.
105105
*
106106
* @param work the {@link TransactionWork} to be applied to a new read transaction.
107107
* @param config configuration for all transactions started to execute the unit of work.
@@ -113,8 +113,8 @@ public interface Session extends Resource, StatementRunner
113113
/**
114114
* Execute given unit of work in a {@link AccessMode#WRITE write} transaction.
115115
* <p>
116-
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or from
117-
* {@link Transaction#close()} or transaction is explicitly marked for failure via {@link Transaction#failure()}.
116+
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or during committing,
117+
* or transaction is explicitly committed via {@link Transaction#commit()} or rolled back via {@link Transaction#rollback()}.
118118
*
119119
* @param work the {@link TransactionWork} to be applied to a new write transaction.
120120
* @param <T> the return type of the given unit of work.
@@ -125,8 +125,8 @@ public interface Session extends Resource, StatementRunner
125125
/**
126126
* Execute given unit of work in a {@link AccessMode#WRITE write} transaction with the specified {@link TransactionConfig configuration}.
127127
* <p>
128-
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or from
129-
* {@link Transaction#close()} or transaction is explicitly marked for failure via {@link Transaction#failure()}.
128+
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or during committing,
129+
* or transaction is explicitly committed via {@link Transaction#commit()} or rolled back via {@link Transaction#rollback()}.
130130
*
131131
* @param work the {@link TransactionWork} to be applied to a new write transaction.
132132
* @param config configuration for all transactions started to execute the unit of work.

driver/src/main/java/org/neo4j/driver/Transaction.java

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,17 @@
2525
* A driver Transaction object corresponds to a server transaction.
2626
* <p>
2727
* Transactions are typically wrapped in a try-with-resources block
28-
* which ensures that <code>COMMIT</code> or <code>ROLLBACK</code>
29-
* occurs correctly on close. Note that <code>ROLLBACK</code> is the
30-
* default action unless {@link #success()} is called before closing.
31-
* <pre class="docTest:TransactionDocIT#classDoc">
28+
* which ensures in case of any error in try block, the transaction is
29+
* automatically rolled back on close. Note that <code>ROLLBACK</code> is the
30+
* default action unless {@link #commit()} is called before closing.
3231
* {@code
3332
* try(Transaction tx = session.beginTransaction())
3433
* {
3534
* tx.run("CREATE (a:Person {name: {x}})", parameters("x", "Alice"));
36-
* tx.success();
35+
* tx.commit();
3736
* }
3837
* }
39-
* </pre>
40-
* Blocking calls are: {@link #success()}, {@link #failure()}, {@link #close()}
38+
* Blocking calls are: {@link #commit()}, {@link #rollback()}, {@link #close()}
4139
* and various overloads of {@link #run(Statement)}.
4240
*
4341
* @see Session#run
@@ -47,36 +45,60 @@
4745
public interface Transaction extends Resource, StatementRunner
4846
{
4947
/**
50-
* Mark this transaction as successful. You must call this method before calling {@link #close()} to have your
51-
* transaction committed.
48+
* Commit this current transaction.
49+
* When this method returns, all outstanding statements in the transaction are guaranteed to
50+
* have completed, meaning any writes you performed are guaranteed to be durably stored.
51+
* No more statement can be executed inside this transaction once this transaction is committed.
52+
* After this method is called, the transaction cannot be committed or rolled back again.
53+
* You must call this method before calling {@link #close()} to have your transaction committed.
54+
* If a transaction is not committed or rolled back before close,
55+
* the transaction will be rolled back by default in {@link #close}.
56+
*
57+
Example:
58+
*
59+
* {@code
60+
* try(Transaction tx = session.beginTransaction() )
61+
* {
62+
* tx.run("CREATE (a:Person {name: {x}})", parameters("x", "Alice"));
63+
* tx.commit();
64+
* }
65+
* }
5266
*/
53-
void success();
67+
void commit();
5468

5569
/**
56-
* Mark this transaction as failed. When you call {@link #close()}, the transaction will value rolled back.
57-
*
58-
* After this method has been called, there is nothing that can be done to "un-mark" it. This is a safety feature
59-
* to make sure no other code calls {@link #success()} and makes a transaction commit that was meant to be rolled
60-
* back.
70+
* Roll back this current transaction.
71+
* No more statement can be executed inside this transaction once this transaction is committed.
72+
* After this method has been called, the transaction cannot be committed or rolled back again.
73+
* If a transaction is not committed or rolled back before close,
74+
* the transaction will be rolled back by default in {@link #close}.
6175
*
6276
* Example:
6377
*
64-
* <pre class="docTest:TransactionDocIT#failure">
6578
* {@code
6679
* try(Transaction tx = session.beginTransaction() )
6780
* {
6881
* tx.run("CREATE (a:Person {name: {x}})", parameters("x", "Alice"));
69-
* tx.failure();
82+
* tx.rollback();
7083
* }
7184
* }
72-
* </pre>
7385
*/
74-
void failure();
86+
void rollback();
7587

7688
/**
77-
* Closing the transaction will complete it - it will commit if {@link #success()} has been called.
78-
* When this method returns, all outstanding statements in the transaction are guaranteed to
79-
* have completed, meaning any writes you performed are guaranteed to be durably stored.
89+
* Close the transaction.
90+
* If the transaction has been {@link #commit() committed} or {@link #rollback() rolled back},
91+
* the close is optional and no operation is performed inside.
92+
* Otherwise, the transaction will be rolled back by default by this method.
93+
*
94+
* Example:
95+
*
96+
* {@code
97+
* try(Transaction tx = session.beginTransaction() )
98+
* {
99+
* tx.run("CREATE (a:Person {name: {x}})", parameters("x", "Alice"));
100+
* }
101+
* }
80102
*/
81103
@Override
82104
void close();

driver/src/main/java/org/neo4j/driver/internal/InternalSession.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,14 @@ private <T> T transaction( AccessMode mode, TransactionWork<T> work, Transaction
145145
return session.retryLogic().retry( () -> {
146146
try ( Transaction tx = beginTransaction( mode, config ) )
147147
{
148-
try
149-
{
150-
T result = work.execute( tx );
151-
tx.success();
152-
return result;
153-
}
154-
catch ( Throwable t )
148+
149+
T result = work.execute( tx );
150+
if ( tx.isOpen() )
155151
{
156-
// mark transaction for failure if the given unit of work threw exception
157-
// this will override any success marks that were made by the unit of work
158-
tx.failure();
159-
throw t;
152+
// commit tx if a user has not explicitly committed or rolled back the transaction
153+
tx.commit();
160154
}
155+
return result;
161156
}
162157
} );
163158
}

driver/src/main/java/org/neo4j/driver/internal/InternalTransaction.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ public InternalTransaction( ExplicitTransaction tx )
3434
}
3535

3636
@Override
37-
public void success()
37+
public void commit()
3838
{
39-
tx.success();
39+
Futures.blockingGet( tx.commitAsync(),
40+
() -> terminateConnectionOnThreadInterrupt( "Thread interrupted while committing the transaction" ) );
4041
}
4142

4243
@Override
43-
public void failure()
44+
public void rollback()
4445
{
45-
tx.failure();
46+
Futures.blockingGet( tx.rollbackAsync(),
47+
() -> terminateConnectionOnThreadInterrupt( "Thread interrupted while rolling back the transaction" ) );
4648
}
4749

4850
@Override

driver/src/main/java/org/neo4j/driver/internal/async/ExplicitTransaction.java

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,6 @@ private enum State
4545
/** The transaction is running with no explicit success or failure marked */
4646
ACTIVE,
4747

48-
/** Running, user marked for success, meaning it'll value committed */
49-
MARKED_SUCCESS,
50-
51-
/** User marked as failed, meaning it'll be rolled back. */
52-
MARKED_FAILED,
53-
5448
/**
5549
* This transaction has been terminated either because of explicit {@link Session#reset()} or because of a
5650
* fatal connection error.
@@ -94,29 +88,9 @@ public CompletionStage<ExplicitTransaction> beginAsync( InternalBookmark initial
9488
} );
9589
}
9690

97-
public void success()
98-
{
99-
if ( state == State.ACTIVE )
100-
{
101-
state = State.MARKED_SUCCESS;
102-
}
103-
}
104-
105-
public void failure()
106-
{
107-
if ( state == State.ACTIVE || state == State.MARKED_SUCCESS )
108-
{
109-
state = State.MARKED_FAILED;
110-
}
111-
}
112-
11391
public CompletionStage<Void> closeAsync()
11492
{
115-
if ( state == State.MARKED_SUCCESS )
116-
{
117-
return commitAsync();
118-
}
119-
else if ( state != State.COMMITTED && state != State.ROLLED_BACK )
93+
if ( isOpen() )
12094
{
12195
return rollbackAsync();
12296
}
@@ -130,7 +104,7 @@ public CompletionStage<Void> commitAsync()
130104
{
131105
if ( state == State.COMMITTED )
132106
{
133-
return completedWithNull();
107+
return failedFuture( new ClientException( "Can't commit, transaction has been committed" ) );
134108
}
135109
else if ( state == State.ROLLED_BACK )
136110
{
@@ -152,7 +126,7 @@ public CompletionStage<Void> rollbackAsync()
152126
}
153127
else if ( state == State.ROLLED_BACK )
154128
{
155-
return completedWithNull();
129+
return failedFuture( new ClientException( "Can't rollback, transaction has been rolled back" ) );
156130
}
157131
else
158132
{
@@ -205,11 +179,6 @@ else if ( state == State.ROLLED_BACK )
205179
{
206180
throw new ClientException( "Cannot run more statements in this transaction, it has been rolled back" );
207181
}
208-
else if ( state == State.MARKED_FAILED )
209-
{
210-
throw new ClientException( "Cannot run more statements in this transaction, it has been marked for failure. " +
211-
"Please either rollback or close this transaction" );
212-
}
213182
else if ( state == State.TERMINATED )
214183
{
215184
throw new ClientException( "Cannot run more statements in this transaction, " +

driver/src/main/java/org/neo4j/driver/internal/async/InternalAsyncSession.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ private <T> void closeTxAfterSucceededTransactionWork( ExplicitTransaction tx, C
196196
{
197197
if ( tx.isOpen() )
198198
{
199-
tx.success();
200-
tx.closeAsync().whenComplete( ( ignore, completionError ) -> {
199+
tx.commitAsync().whenComplete( ( ignore, completionError ) -> {
201200
Throwable commitError = Futures.completionExceptionCause( completionError );
202201
if ( commitError != null )
203202
{

driver/src/test/java/org/neo4j/driver/integration/BookmarkIT.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void bookmarkRemainsAfterRolledBackTx()
112112
try ( Transaction tx = session.beginTransaction() )
113113
{
114114
tx.run( "CREATE (a:Person)" );
115-
tx.failure();
115+
tx.rollback();
116116
}
117117

118118
assertEquals( bookmark, session.lastBookmark() );
@@ -130,9 +130,8 @@ void bookmarkRemainsAfterTxFailure()
130130

131131
Transaction tx = session.beginTransaction();
132132
tx.run( "RETURN" );
133-
tx.success();
134133

135-
assertThrows( ClientException.class, tx::close );
134+
assertThrows( ClientException.class, tx::commit );
136135
assertEquals( bookmark, session.lastBookmark() );
137136
}
138137

@@ -210,7 +209,7 @@ private static void createNodeInTx( Session session )
210209
try ( Transaction tx = session.beginTransaction() )
211210
{
212211
tx.run( "CREATE (a:Person)" );
213-
tx.success();
212+
tx.commit();
214213
}
215214
}
216215
}

driver/src/test/java/org/neo4j/driver/integration/ConnectionHandlingIT.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ void connectionUsedForTransactionReturnedToThePoolWhenTransactionCommitted()
219219
verify( connection1, never() ).release();
220220

221221
StatementResult result = createNodes( 5, tx );
222-
tx.success();
222+
tx.commit();
223223
tx.close();
224224

225225
Connection connection2 = connectionPool.lastAcquiredConnectionSpy;
@@ -240,7 +240,7 @@ void connectionUsedForTransactionReturnedToThePoolWhenTransactionRolledBack()
240240
verify( connection1, never() ).release();
241241

242242
StatementResult result = createNodes( 8, tx );
243-
tx.failure();
243+
tx.rollback();
244244
tx.close();
245245

246246
Connection connection2 = connectionPool.lastAcquiredConnectionSpy;
@@ -268,9 +268,8 @@ void connectionUsedForTransactionReturnedToThePoolWhenTransactionFailsToCommitte
268268

269269
// property existence constraints are verified on commit, try to violate it
270270
tx.run( "CREATE (:Book)" );
271-
tx.success();
272271

273-
assertThrows( ClientException.class, tx::close );
272+
assertThrows( ClientException.class, tx::commit );
274273

275274
// connection should have been released after failed node creation
276275
verify( connection2 ).release();

driver/src/test/java/org/neo4j/driver/integration/ConnectionPoolIT.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,7 @@ private static void startAndCloseTransactions( Driver driver, int txCount )
177177
}
178178
for ( Transaction tx : transactions )
179179
{
180-
tx.success();
181-
tx.close();
180+
tx.commit();
182181
}
183182
for ( Session session : sessions )
184183
{

driver/src/test/java/org/neo4j/driver/integration/ErrorIT.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,14 @@ void shouldHandleFailureAtCommitTime()
158158
// given
159159
Transaction tx = session.beginTransaction();
160160
tx.run( "CREATE CONSTRAINT ON (a:`" + label + "`) ASSERT a.name IS UNIQUE" );
161-
tx.success();
162-
tx.close();
161+
tx.commit();
163162

164163
// and
165164
tx = session.beginTransaction();
166165
tx.run( "CREATE INDEX ON :`" + label + "`(name)" );
167-
tx.success();
168166

169167
// then expect
170-
ClientException e = assertThrows( ClientException.class, tx::close );
168+
ClientException e = assertThrows( ClientException.class, tx::commit );
171169
assertThat( e.getMessage(), containsString( label ) );
172170
assertThat( e.getMessage(), containsString( "name" ) );
173171
}

0 commit comments

Comments
 (0)