@@ -796,6 +796,120 @@ describe('session', () => {
796796 } ) ;
797797 } ) ;
798798
799+ it ( 'should interrupt query waiting on a lock when closed' , done => {
800+ if ( ! serverIs31OrLater ( done ) ) {
801+ // locks are transaction termination aware by default only in 3.1+
802+ return ;
803+ }
804+
805+ session . run ( 'CREATE ()' ) . then ( ( ) => {
806+ session . close ( ( ) => {
807+ const session1 = driver . session ( ) ;
808+ const session2 = driver . session ( ) ;
809+ const tx1 = session1 . beginTransaction ( ) ;
810+
811+ tx1 . run ( 'MATCH (n) SET n.id = 1 RETURN 42 AS answer' ) . then ( result => {
812+ // node is now locked by tx1
813+ expect ( result . records . length ) . toEqual ( 1 ) ;
814+ expect ( result . records [ 0 ] . get ( 0 ) . toNumber ( ) ) . toEqual ( 42 ) ;
815+
816+ // this query should get stuck waiting for the lock
817+ session2 . run ( 'MATCH (n) SET n.id = 2 RETURN 42 AS answer' ) . catch ( error => {
818+ expectTransactionTerminatedError ( error ) ;
819+ tx1 . commit ( ) . then ( ( ) => {
820+ readAllNodeIds ( ) . then ( ids => {
821+ expect ( ids ) . toEqual ( [ 1 ] ) ;
822+ done ( ) ;
823+ } ) ;
824+ } ) ;
825+ } ) ;
826+
827+ setTimeout ( ( ) => {
828+ // close session after a while
829+ session2 . close ( ) ;
830+ } , 1000 ) ;
831+ } ) ;
832+ } ) ;
833+ } ) ;
834+ } ) ;
835+
836+ it ( 'should interrupt transaction waiting on a lock when closed' , done => {
837+ if ( ! serverIs31OrLater ( done ) ) {
838+ // locks are transaction termination aware by default only in 3.1+
839+ return ;
840+ }
841+
842+ session . run ( 'CREATE ()' ) . then ( ( ) => {
843+ session . close ( ( ) => {
844+ const session1 = driver . session ( ) ;
845+ const session2 = driver . session ( ) ;
846+ const tx1 = session1 . beginTransaction ( ) ;
847+ const tx2 = session2 . beginTransaction ( ) ;
848+
849+ tx1 . run ( 'MATCH (n) SET n.id = 1 RETURN 42 AS answer' ) . then ( result => {
850+ // node is now locked by tx1
851+ expect ( result . records . length ) . toEqual ( 1 ) ;
852+ expect ( result . records [ 0 ] . get ( 0 ) . toNumber ( ) ) . toEqual ( 42 ) ;
853+
854+ // this query should get stuck waiting for the lock
855+ tx2 . run ( 'MATCH (n) SET n.id = 2 RETURN 42 AS answer' ) . catch ( error => {
856+ expectTransactionTerminatedError ( error ) ;
857+ tx1 . commit ( ) . then ( ( ) => {
858+ readAllNodeIds ( ) . then ( ids => {
859+ expect ( ids ) . toEqual ( [ 1 ] ) ;
860+ done ( ) ;
861+ } ) ;
862+ } ) ;
863+ } ) ;
864+
865+ setTimeout ( ( ) => {
866+ // close session after a while
867+ session2 . close ( ) ;
868+ } , 1000 ) ;
869+ } ) ;
870+ } ) ;
871+ } ) ;
872+ } ) ;
873+
874+ it ( 'should interrupt transaction function waiting on a lock when closed' , done => {
875+ if ( ! serverIs31OrLater ( done ) ) {
876+ // locks are transaction termination aware by default only in 3.1+
877+ return ;
878+ }
879+
880+ session . run ( 'CREATE ()' ) . then ( ( ) => {
881+ session . close ( ( ) => {
882+ const session1 = driver . session ( ) ;
883+ const session2 = driver . session ( ) ;
884+ const tx1 = session1 . beginTransaction ( ) ;
885+
886+ tx1 . run ( 'MATCH (n) SET n.id = 1 RETURN 42 AS answer' ) . then ( result => {
887+ // node is now locked by tx1
888+ expect ( result . records . length ) . toEqual ( 1 ) ;
889+ expect ( result . records [ 0 ] . get ( 0 ) . toNumber ( ) ) . toEqual ( 42 ) ;
890+
891+ session2 . writeTransaction ( tx2 => {
892+ // this query should get stuck waiting for the lock
893+ return tx2 . run ( 'MATCH (n) SET n.id = 2 RETURN 42 AS answer' ) . catch ( error => {
894+ expectTransactionTerminatedError ( error ) ;
895+ tx1 . commit ( ) . then ( ( ) => {
896+ readAllNodeIds ( ) . then ( ids => {
897+ expect ( ids ) . toEqual ( [ 1 ] ) ;
898+ done ( ) ;
899+ } ) ;
900+ } ) ;
901+ } ) ;
902+ } ) ;
903+
904+ setTimeout ( ( ) => {
905+ // close session after a while
906+ session2 . close ( ) ;
907+ } , 1000 ) ;
908+ } ) ;
909+ } ) ;
910+ } ) ;
911+ } ) ;
912+
799913 function serverIs31OrLater ( done ) {
800914 // lazy way of checking the version number
801915 // if server has been set we know it is at least 3.1
@@ -840,4 +954,21 @@ describe('session', () => {
840954 expect ( bookmark ) . toBeDefined ( ) ;
841955 expect ( bookmark ) . not . toBeNull ( ) ;
842956 }
957+
958+ function expectTransactionTerminatedError ( error ) {
959+ expect ( error . message . toLowerCase ( ) . indexOf ( 'transaction terminated' ) >= 0 ) . toBeTruthy ( ) ;
960+ }
961+
962+ function readAllNodeIds ( ) {
963+ return new Promise ( ( resolve , reject ) => {
964+ const session = driver . session ( ) ;
965+ session . run ( 'MATCH (n) RETURN n.id' ) . then ( result => {
966+ const ids = result . records . map ( record => record . get ( 0 ) . toNumber ( ) ) ;
967+ session . close ( ) ;
968+ resolve ( ids ) ;
969+ } ) . catch ( error => {
970+ reject ( error ) ;
971+ } ) ;
972+ } ) ;
973+ }
843974} ) ;
0 commit comments