Skip to content

Commit f74689f

Browse files
daprahamiankiku-jw
authored andcommitted
docs(transactions): adding examples for transactions
Fixes NODE-1478
1 parent 1d85497 commit f74689f

File tree

1 file changed

+277
-0
lines changed

1 file changed

+277
-0
lines changed

test/functional/operation_promises_example_tests.js

+277
Original file line numberDiff line numberDiff line change
@@ -7240,4 +7240,281 @@ describe('Operation (Promises)', function() {
72407240
// END
72417241
}
72427242
});
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+
});
72437520
});

0 commit comments

Comments
 (0)