@@ -7240,4 +7240,281 @@ describe('Operation (Promises)', function() {
7240
7240
// END
7241
7241
}
7242
7242
} ) ;
7243
+
7244
+ describe ( 'Transaction Examples' , function ( ) {
7245
+ before ( function ( ) {
7246
+ const configuration = this . configuration ;
7247
+ const client = configuration . newClient ( configuration . writeConcernMax ( ) ) ;
7248
+
7249
+ return client
7250
+ . connect ( )
7251
+ . then ( ( ) => client . db ( 'hr' ) . createCollection ( 'employees' ) )
7252
+ . then ( ( ) => client . db ( 'reporting' ) . createCollection ( 'events' ) ) ;
7253
+ } ) ;
7254
+
7255
+ // Start Transactions Intro Example 1
7256
+ it ( 'should be able to run transactions example 1' , {
7257
+ metadata : { requires : { topology : [ 'replicaset' ] , mongodb : '>=3.8.0' } } ,
7258
+ test : function ( ) {
7259
+ const configuration = this . configuration ;
7260
+ const client = configuration . newClient ( configuration . writeConcernMax ( ) ) ;
7261
+
7262
+ // BEGIN
7263
+ function updateEmployeeInfo ( client ) {
7264
+ return client . withSession ( session => {
7265
+ function commit ( ) {
7266
+ return session . commitTransaction ( ) . catch ( e => {
7267
+ if ( e . errorLabels && e . errorLabels . indexOf ( 'UnknownTransactionCommitResult' ) < 0 ) {
7268
+ // LINE console.log('Transaction aborted. Caught exception during transaction.');
7269
+ return commit ( ) ;
7270
+ }
7271
+
7272
+ // LINE console.log('Error during commit ...');
7273
+ throw e ;
7274
+ } ) ;
7275
+ }
7276
+
7277
+ const employeesCollection = client . db ( 'hr' ) . collection ( 'employees' ) ;
7278
+ const eventsCollection = client . db ( 'reporting' ) . collection ( 'events' ) ;
7279
+
7280
+ session . startTransaction ( {
7281
+ readConcern : { level : 'snapshot' } ,
7282
+ writeConcern : { w : 'majority' }
7283
+ } ) ;
7284
+
7285
+ return employeesCollection
7286
+ . updateOne ( { employee : 3 } , { $set : { status : 'Inactive' } } , { session } )
7287
+ . then ( ( ) => {
7288
+ return eventsCollection . insertOne (
7289
+ {
7290
+ employee : 3 ,
7291
+ status : { new : 'Inactive' , old : 'Active' }
7292
+ } ,
7293
+ { session }
7294
+ ) ;
7295
+ } )
7296
+ . catch ( e => {
7297
+ // LINE console.log('caugh exception during transaction, aborting')
7298
+ return session . abortTransaction ( ) . then ( ( ) => Promise . reject ( e ) ) ;
7299
+ } )
7300
+ . then ( ( ) => commit ( ) )
7301
+ . then ( ( ) => {
7302
+ // LINE console.log('Transaction committed');
7303
+ } ) ;
7304
+ } ) ;
7305
+ // END
7306
+ }
7307
+ client
7308
+ . connect ( )
7309
+ . then ( ( ) => updateEmployeeInfo ( client ) )
7310
+ . then ( ( ) => client . close ( ) ) ;
7311
+ }
7312
+ } ) ;
7313
+ // End Transactions Intro Example 1
7314
+
7315
+ // Start Transactions Retry Example 1
7316
+ it ( 'should be able to run transactions retry example 1' , {
7317
+ metadata : { requires : { topology : [ 'replicaset' ] , mongodb : '>=3.8.0' } } ,
7318
+ test : function ( ) {
7319
+ // BEGIN
7320
+ function runTransactionWithRetry ( txnFunc , client , session ) {
7321
+ return txnFunc ( client , session ) . catch ( error => {
7322
+ // LINE console.log('Transaction aborted. Caught exception during transaction.');
7323
+
7324
+ // If transient error, retry the whole transaction
7325
+ if ( error . errorLabels && error . errorLabels . indexOf ( 'TransientTransactionError' ) < 0 ) {
7326
+ // LINE console.log('TransientTransactionError, retrying transaction ...');
7327
+ return runTransactionWithRetry ( txnFunc , client , session ) ;
7328
+ }
7329
+
7330
+ throw error ;
7331
+ } ) ;
7332
+ }
7333
+ // END
7334
+
7335
+ function updateEmployeeInfo ( client , session ) {
7336
+ session . startTransaction ( {
7337
+ readConcern : { level : 'snapshot' } ,
7338
+ writeConcern : { w : 'majority' }
7339
+ } ) ;
7340
+
7341
+ const employeesCollection = client . db ( 'hr' ) . collection ( 'employees' ) ;
7342
+ const eventsCollection = client . db ( 'reporting' ) . collection ( 'events' ) ;
7343
+
7344
+ return employeesCollection
7345
+ . updateOne ( { employee : 3 } , { $set : { status : 'Inactive' } } , { session } )
7346
+ . then ( ( ) => {
7347
+ return eventsCollection . insertOne (
7348
+ {
7349
+ employee : 3 ,
7350
+ status : { new : 'Inactive' , old : 'Active' }
7351
+ } ,
7352
+ { session }
7353
+ ) ;
7354
+ } )
7355
+ . then ( ( ) => session . commitTransaction ( ) )
7356
+ . catch ( e => {
7357
+ return session . abortTransaction ( ) . then ( ( ) => Promise . reject ( e ) ) ;
7358
+ } ) ;
7359
+ }
7360
+ const configuration = this . configuration ;
7361
+ const client = configuration . newClient ( configuration . writeConcernMax ( ) ) ;
7362
+
7363
+ return client
7364
+ . connect ( )
7365
+ . then ( ( ) =>
7366
+ client . withSession ( session =>
7367
+ runTransactionWithRetry ( updateEmployeeInfo , client , session )
7368
+ )
7369
+ )
7370
+ . then ( ( ) => client . close ( ) ) ;
7371
+ }
7372
+ } ) ;
7373
+
7374
+ // End Transactions Retry Example 1
7375
+
7376
+ // Start Transactions Retry Example 2
7377
+ it ( 'should be able to run transactions retry example 2' , {
7378
+ metadata : { requires : { topology : [ 'replicaset' ] , mongodb : '>=3.8.0' } } ,
7379
+ test : function ( ) {
7380
+ // BEGIN
7381
+ function commitWithRetry ( session ) {
7382
+ return (
7383
+ session
7384
+ . commitTransaction ( )
7385
+ // LINE .then(() => console.log('Transaction committed.'))
7386
+ . catch ( error => {
7387
+ if (
7388
+ error . errorLabels &&
7389
+ error . errorLabels . indexOf ( 'UnknownTransactionCommitResult' ) < 0
7390
+ ) {
7391
+ // LINE console.log('UnknownTransactionCommitResult, retrying commit operation ...');
7392
+ return commitWithRetry ( session ) ;
7393
+ }
7394
+ // LINE console.log('Error during commit ...');
7395
+ throw error ;
7396
+ } )
7397
+ ) ;
7398
+ }
7399
+ // END
7400
+
7401
+ function updateEmployeeInfo ( client , session ) {
7402
+ session . startTransaction ( {
7403
+ readConcern : { level : 'snapshot' } ,
7404
+ writeConcern : { w : 'majority' }
7405
+ } ) ;
7406
+
7407
+ const employeesCollection = client . db ( 'hr' ) . collection ( 'employees' ) ;
7408
+ const eventsCollection = client . db ( 'reporting' ) . collection ( 'events' ) ;
7409
+
7410
+ return employeesCollection
7411
+ . updateOne ( { employee : 3 } , { $set : { status : 'Inactive' } } , { session } )
7412
+ . then ( ( ) => {
7413
+ return eventsCollection . insertOne (
7414
+ {
7415
+ employee : 3 ,
7416
+ status : { new : 'Inactive' , old : 'Active' }
7417
+ } ,
7418
+ { session }
7419
+ ) ;
7420
+ } )
7421
+ . then ( ( ) => commitWithRetry ( session ) )
7422
+ . catch ( e => {
7423
+ return session . abortTransaction ( ) . then ( ( ) => Promise . reject ( e ) ) ;
7424
+ } ) ;
7425
+ }
7426
+ const configuration = this . configuration ;
7427
+ const client = configuration . newClient ( configuration . writeConcernMax ( ) ) ;
7428
+
7429
+ return client
7430
+ . connect ( )
7431
+ . then ( ( ) => client . withSession ( session => updateEmployeeInfo ( client , session ) ) )
7432
+ . then ( ( ) => client . close ( ) ) ;
7433
+ }
7434
+ } ) ;
7435
+ // End Transactions Retry Example 2
7436
+
7437
+ // Start Transactions Retry Example 3
7438
+ it ( 'should be able to run transactions retry example 3' , {
7439
+ metadata : { requires : { topology : [ 'replicaset' ] , mongodb : '>=3.8.0' } } ,
7440
+ test : function ( ) {
7441
+ const configuration = this . configuration ;
7442
+ const client = configuration . newClient ( configuration . writeConcernMax ( ) ) ;
7443
+
7444
+ // BEGIN
7445
+ function commitWithRetry ( session ) {
7446
+ return (
7447
+ session
7448
+ . commitTransaction ( )
7449
+ // LINE .then(() => console.log('Transaction committed.'))
7450
+ . catch ( error => {
7451
+ if (
7452
+ error . errorLabels &&
7453
+ error . errorLabels . indexOf ( 'UnknownTransactionCommitResult' ) < 0
7454
+ ) {
7455
+ // LINE console.log('UnknownTransactionCommitResult, retrying commit operation ...');
7456
+ return commitWithRetry ( session ) ;
7457
+ }
7458
+ // LINE console.log('Error during commit ...');
7459
+ throw error ;
7460
+ } )
7461
+ ) ;
7462
+ }
7463
+
7464
+ function runTransactionWithRetry ( txnFunc , client , session ) {
7465
+ return txnFunc ( client , session ) . catch ( error => {
7466
+ // LINE console.log('Transaction aborted. Caught exception during transaction.');
7467
+
7468
+ // If transient error, retry the whole transaction
7469
+ if ( error . errorLabels && error . errorLabels . indexOf ( 'TransientTransactionError' ) < 0 ) {
7470
+ // LINE console.log('TransientTransactionError, retrying transaction ...');
7471
+ return runTransactionWithRetry ( txnFunc , client , session ) ;
7472
+ }
7473
+
7474
+ throw error ;
7475
+ } ) ;
7476
+ }
7477
+
7478
+ function updateEmployeeInfo ( client , session ) {
7479
+ const employeesCollection = client . db ( 'hr' ) . collection ( 'employees' ) ;
7480
+ const eventsCollection = client . db ( 'reporting' ) . collection ( 'events' ) ;
7481
+
7482
+ session . startTransaction ( {
7483
+ readConcern : { level : 'snapshot' } ,
7484
+ writeConcern : { w : 'majority' }
7485
+ } ) ;
7486
+
7487
+ return employeesCollection
7488
+ . updateOne ( { employee : 3 } , { $set : { status : 'Inactive' } } , { session } )
7489
+ . then ( ( ) => {
7490
+ return eventsCollection . insertOne (
7491
+ {
7492
+ employee : 3 ,
7493
+ status : { new : 'Inactive' , old : 'Active' }
7494
+ } ,
7495
+ { session }
7496
+ ) ;
7497
+ } )
7498
+ . catch ( e => {
7499
+ // LINE console.log('caugh exception during transaction, aborting')
7500
+ return session . abortTransaction ( ) . then ( ( ) => Promise . reject ( e ) ) ;
7501
+ } )
7502
+ . then ( ( ) => commitWithRetry ( session ) ) ;
7503
+ }
7504
+
7505
+ // LINE const { MongoClient } = require('mongodb'),
7506
+ // LINE const client = new MongoClient('myRepl/mongodb0.example.net:27017,mongodb1.example.net:27017,mongodb2.example.net:27017');
7507
+ return client
7508
+ . connect ( )
7509
+ . then ( ( ) =>
7510
+ client . withSession ( session =>
7511
+ runTransactionWithRetry ( updateEmployeeInfo , client , session )
7512
+ )
7513
+ )
7514
+ . then ( ( ) => client . close ( ) ) ;
7515
+ // END
7516
+ }
7517
+ } ) ;
7518
+ // End Transactions Retry Example 3
7519
+ } ) ;
7243
7520
} ) ;
0 commit comments