@@ -49,10 +49,13 @@ public class NetworkSession implements Session
49
49
@ Override
50
50
public void run ()
51
51
{
52
- if ( currentTransaction != null )
52
+ synchronized ( NetworkSession . this )
53
53
{
54
- lastBookmark = currentTransaction .bookmark ();
55
- currentTransaction = null ;
54
+ if ( currentTransaction != null )
55
+ {
56
+ lastBookmark = currentTransaction .bookmark ();
57
+ currentTransaction = null ;
58
+ }
56
59
}
57
60
}
58
61
};
@@ -73,9 +76,9 @@ public StatementResult run( String statementText )
73
76
}
74
77
75
78
@ Override
76
- public StatementResult run ( String statementText , Map <String , Object > statementParameters )
79
+ public StatementResult run ( String statementText , Map <String ,Object > statementParameters )
77
80
{
78
- Value params = statementParameters == null ? Values .EmptyMap : value (statementParameters );
81
+ Value params = statementParameters == null ? Values .EmptyMap : value ( statementParameters );
79
82
return run ( statementText , params );
80
83
}
81
84
@@ -97,21 +100,24 @@ public StatementResult run( Statement statement )
97
100
{
98
101
ensureConnectionIsValidBeforeRunningSession ();
99
102
InternalStatementResult cursor = new InternalStatementResult ( connection , null , statement );
100
- connection .run ( statement .text (), statement .parameters ().asMap ( Values .ofValue () ), cursor .runResponseCollector () );
103
+ connection .run ( statement .text (), statement .parameters ().asMap ( Values .ofValue () ),
104
+ cursor .runResponseCollector () );
101
105
connection .pullAll ( cursor .pullAllResponseCollector () );
102
106
connection .flush ();
103
107
return cursor ;
104
108
}
105
109
106
- public void reset ()
110
+ public synchronized void reset ()
107
111
{
108
112
ensureSessionIsOpen ();
109
113
ensureNoUnrecoverableError ();
110
114
ensureConnectionIsOpen ();
111
115
112
- if ( currentTransaction != null )
116
+ if ( currentTransaction != null )
113
117
{
114
118
currentTransaction .markToClose ();
119
+ lastBookmark = currentTransaction .bookmark ();
120
+ currentTransaction = null ;
115
121
}
116
122
connection .resetAsync ();
117
123
}
@@ -126,21 +132,24 @@ public boolean isOpen()
126
132
public void close ()
127
133
{
128
134
// Use atomic operation to protect from closing the connection twice (putting back to the pool twice).
129
- if ( !isOpen .compareAndSet ( true , false ) )
135
+ if ( !isOpen .compareAndSet ( true , false ) )
130
136
{
131
137
throw new ClientException ( "This session has already been closed." );
132
138
}
133
139
else
134
140
{
135
- if ( currentTransaction != null )
141
+ synchronized ( this )
136
142
{
137
- try
138
- {
139
- currentTransaction .close ();
140
- }
141
- catch ( Throwable e )
143
+ if ( currentTransaction != null )
142
144
{
143
- // Best-effort
145
+ try
146
+ {
147
+ currentTransaction .close ();
148
+ }
149
+ catch ( Throwable e )
150
+ {
151
+ // Best-effort
152
+ }
144
153
}
145
154
}
146
155
try
@@ -167,7 +176,7 @@ public Transaction beginTransaction()
167
176
}
168
177
169
178
@ Override
170
- public Transaction beginTransaction ( String bookmark )
179
+ public synchronized Transaction beginTransaction ( String bookmark )
171
180
{
172
181
ensureConnectionIsValidBeforeOpeningTransaction ();
173
182
currentTransaction = new ExplicitTransaction ( connection , txCleanup , bookmark );
@@ -224,7 +233,7 @@ private void ensureConnectionIsValidBeforeOpeningTransaction()
224
233
@ Override
225
234
protected void finalize () throws Throwable
226
235
{
227
- if ( isOpen .compareAndSet ( true , false ) )
236
+ if ( isOpen .compareAndSet ( true , false ) )
228
237
{
229
238
logger .error ( "Neo4j Session object leaked, please ensure that your application calls the `close` " +
230
239
"method on Sessions before disposing of the objects." , null );
@@ -235,14 +244,15 @@ protected void finalize() throws Throwable
235
244
236
245
private void ensureNoUnrecoverableError ()
237
246
{
238
- if ( connection .hasUnrecoverableErrors () )
247
+ if ( connection .hasUnrecoverableErrors () )
239
248
{
240
249
throw new ClientException ( "Cannot run more statements in the current session as an unrecoverable error " +
241
250
"has happened. Please close the current session and re-run your statement in a" +
242
251
" new session." );
243
252
}
244
253
}
245
254
255
+ //should be called from a synchronized block
246
256
private void ensureNoOpenTransactionBeforeRunningSession ()
247
257
{
248
258
if ( currentTransaction != null )
@@ -252,6 +262,7 @@ private void ensureNoOpenTransactionBeforeRunningSession()
252
262
}
253
263
}
254
264
265
+ //should be called from a synchronized block
255
266
private void ensureNoOpenTransactionBeforeOpeningTransaction ()
256
267
{
257
268
if ( currentTransaction != null )
@@ -273,12 +284,13 @@ private void ensureConnectionIsOpen()
273
284
274
285
private void ensureSessionIsOpen ()
275
286
{
276
- if ( !isOpen () )
287
+ if ( !isOpen () )
277
288
{
278
289
throw new ClientException (
279
290
"No more interaction with this session is allowed " +
280
291
"as the current session is already closed or marked as closed. " +
281
- "You get this error either because you have a bad reference to a session that has already be closed " +
292
+ "You get this error either because you have a bad reference to a session that has already be " +
293
+ "closed " +
282
294
"or you are trying to reuse a session that you have called `reset` on it." );
283
295
}
284
296
}
0 commit comments