@@ -796,6 +796,120 @@ describe('session', () => {
796
796
} ) ;
797
797
} ) ;
798
798
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
+
799
913
function serverIs31OrLater ( done ) {
800
914
// lazy way of checking the version number
801
915
// if server has been set we know it is at least 3.1
@@ -840,4 +954,21 @@ describe('session', () => {
840
954
expect ( bookmark ) . toBeDefined ( ) ;
841
955
expect ( bookmark ) . not . toBeNull ( ) ;
842
956
}
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
+ }
843
974
} ) ;
0 commit comments