@@ -49,10 +49,13 @@ public class NetworkSession implements Session
4949 @ Override
5050 public void run ()
5151 {
52- if ( currentTransaction != null )
52+ synchronized ( NetworkSession . this )
5353 {
54- lastBookmark = currentTransaction .bookmark ();
55- currentTransaction = null ;
54+ if ( currentTransaction != null )
55+ {
56+ lastBookmark = currentTransaction .bookmark ();
57+ currentTransaction = null ;
58+ }
5659 }
5760 }
5861 };
@@ -73,9 +76,9 @@ public StatementResult run( String statementText )
7376 }
7477
7578 @ Override
76- public StatementResult run ( String statementText , Map <String , Object > statementParameters )
79+ public StatementResult run ( String statementText , Map <String ,Object > statementParameters )
7780 {
78- Value params = statementParameters == null ? Values .EmptyMap : value (statementParameters );
81+ Value params = statementParameters == null ? Values .EmptyMap : value ( statementParameters );
7982 return run ( statementText , params );
8083 }
8184
@@ -97,21 +100,24 @@ public StatementResult run( Statement statement )
97100 {
98101 ensureConnectionIsValidBeforeRunningSession ();
99102 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 () );
101105 connection .pullAll ( cursor .pullAllResponseCollector () );
102106 connection .flush ();
103107 return cursor ;
104108 }
105109
106- public void reset ()
110+ public synchronized void reset ()
107111 {
108112 ensureSessionIsOpen ();
109113 ensureNoUnrecoverableError ();
110114 ensureConnectionIsOpen ();
111115
112- if ( currentTransaction != null )
116+ if ( currentTransaction != null )
113117 {
114118 currentTransaction .markToClose ();
119+ lastBookmark = currentTransaction .bookmark ();
120+ currentTransaction = null ;
115121 }
116122 connection .resetAsync ();
117123 }
@@ -126,21 +132,24 @@ public boolean isOpen()
126132 public void close ()
127133 {
128134 // 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 ) )
130136 {
131137 throw new ClientException ( "This session has already been closed." );
132138 }
133139 else
134140 {
135- if ( currentTransaction != null )
141+ synchronized ( this )
136142 {
137- try
138- {
139- currentTransaction .close ();
140- }
141- catch ( Throwable e )
143+ if ( currentTransaction != null )
142144 {
143- // Best-effort
145+ try
146+ {
147+ currentTransaction .close ();
148+ }
149+ catch ( Throwable e )
150+ {
151+ // Best-effort
152+ }
144153 }
145154 }
146155 try
@@ -167,7 +176,7 @@ public Transaction beginTransaction()
167176 }
168177
169178 @ Override
170- public Transaction beginTransaction ( String bookmark )
179+ public synchronized Transaction beginTransaction ( String bookmark )
171180 {
172181 ensureConnectionIsValidBeforeOpeningTransaction ();
173182 currentTransaction = new ExplicitTransaction ( connection , txCleanup , bookmark );
@@ -224,7 +233,7 @@ private void ensureConnectionIsValidBeforeOpeningTransaction()
224233 @ Override
225234 protected void finalize () throws Throwable
226235 {
227- if ( isOpen .compareAndSet ( true , false ) )
236+ if ( isOpen .compareAndSet ( true , false ) )
228237 {
229238 logger .error ( "Neo4j Session object leaked, please ensure that your application calls the `close` " +
230239 "method on Sessions before disposing of the objects." , null );
@@ -235,14 +244,15 @@ protected void finalize() throws Throwable
235244
236245 private void ensureNoUnrecoverableError ()
237246 {
238- if ( connection .hasUnrecoverableErrors () )
247+ if ( connection .hasUnrecoverableErrors () )
239248 {
240249 throw new ClientException ( "Cannot run more statements in the current session as an unrecoverable error " +
241250 "has happened. Please close the current session and re-run your statement in a" +
242251 " new session." );
243252 }
244253 }
245254
255+ //should be called from a synchronized block
246256 private void ensureNoOpenTransactionBeforeRunningSession ()
247257 {
248258 if ( currentTransaction != null )
@@ -252,6 +262,7 @@ private void ensureNoOpenTransactionBeforeRunningSession()
252262 }
253263 }
254264
265+ //should be called from a synchronized block
255266 private void ensureNoOpenTransactionBeforeOpeningTransaction ()
256267 {
257268 if ( currentTransaction != null )
@@ -273,12 +284,13 @@ private void ensureConnectionIsOpen()
273284
274285 private void ensureSessionIsOpen ()
275286 {
276- if ( !isOpen () )
287+ if ( !isOpen () )
277288 {
278289 throw new ClientException (
279290 "No more interaction with this session is allowed " +
280291 "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 " +
282294 "or you are trying to reuse a session that you have called `reset` on it." );
283295 }
284296 }
0 commit comments