Skip to content

Commit a5cf951

Browse files
author
Zhen Li
committed
Removed Transaction#success and Transaction#failure
Changed the behaviour of `AsyncTransaction#commitAsync` and `AsyncTransaction#rollbackAsync` to throw error when committing/rolling back second time. A transaction can be allowed to commit or rollback once, but closed multiple times. This bring the behaviour of commit and rollback the same as 4.0 core API, as well as all other language drivers.
1 parent 58aa548 commit a5cf951

29 files changed

+373
-376
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public interface Session extends Resource, StatementRunner
8989
* Execute given unit of work in a {@link AccessMode#READ read} transaction.
9090
* <p>
9191
* 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()}.
92+
* {@link Transaction#close()} or transaction is explicitly 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.
@@ -101,7 +101,7 @@ public interface Session extends Resource, StatementRunner
101101
* Execute given unit of work in a {@link AccessMode#READ read} transaction with the specified {@link TransactionConfig configuration}.
102102
* <p>
103103
* 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()}.
104+
* {@link Transaction#close()} or transaction is explicitly 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.
@@ -114,7 +114,7 @@ public interface Session extends Resource, StatementRunner
114114
* Execute given unit of work in a {@link AccessMode#WRITE write} transaction.
115115
* <p>
116116
* 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()}.
117+
* {@link Transaction#close()} or transaction is explicitly 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.
@@ -126,7 +126,7 @@ public interface Session extends Resource, StatementRunner
126126
* Execute given unit of work in a {@link AccessMode#WRITE write} transaction with the specified {@link TransactionConfig configuration}.
127127
* <p>
128128
* 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()}.
129+
* {@link Transaction#close()} or transaction is explicitly 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 & 3 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,7 +130,7 @@ void bookmarkRemainsAfterTxFailure()
130130

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

135135
assertThrows( ClientException.class, tx::close );
136136
assertEquals( bookmark, session.lastBookmark() );
@@ -210,7 +210,7 @@ private static void createNodeInTx( Session session )
210210
try ( Transaction tx = session.beginTransaction() )
211211
{
212212
tx.run( "CREATE (a:Person)" );
213-
tx.success();
213+
tx.commit();
214214
}
215215
}
216216
}

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

Lines changed: 3 additions & 3 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,7 +268,7 @@ void connectionUsedForTransactionReturnedToThePoolWhenTransactionFailsToCommitte
268268

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

273273
assertThrows( ClientException.class, tx::close );
274274

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 & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,12 @@ 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();
166+
tx.commit();
168167

169168
// then expect
170169
ClientException e = assertThrows( ClientException.class, tx::close );

0 commit comments

Comments
 (0)