Hello All,
In this we will discuss about how to perform two phase commit in MongoDB.
Consider a example where funds will be transferred from one account to another. In a relation database approach we just subtract fund from account a and add same amount to another account. To complete this task in mongoDB the concept of two phase commit will perform as shown in below example.
The examples use following two collections:
1. A collection named accounts to store account information.
2. A collection named transactions to store information on the fund transfer transactions.
Initialize collection with A and B Accounts
Below is mongo code for insert document in accounts collection.
db.accounts.insert(
[
{ _id: "A", balance: 1000, pendingTransactions: [] },
{ _id: "B", balance: 1000, pendingTransactions: [] }
]
)
Initialize Transfer Record
Insert records to transaction collection to perform transfer of money. The document in transaction collection include following fields.
db.transactions.insert(
{ _id: 1, source: "A", destination: "B", value: 100, state: "initial", lastModified: new Date() }
)
Transfer Funds Between Accounts Using Two-Phase Commit
1)Retrieve the transaction to start.
var t = db.transactions.findOne( { state: "initial" } )
{ "_id" : 1, "source" : "A", "destination" : "B", "value" : 100, "state" : "initial", "lastModified" : ISODate("2014-07-11T20:39:26.345Z") }
2)Update transaction state to pending.
db.transactions.update(
{ _id: t._id, state: "initial" },
{
$set: { state: "pending" },
$currentDate: { lastModified: true }
}
)
3)Apply the transaction to both accounts.
db.accounts.update(
{ _id: t.source, pendingTransactions: { $ne: t._id } },
{ $inc: { balance: -t.value }, $push: { pendingTransactions: t._id } }
)
db.accounts.update(
{ _id: t.destination, pendingTransactions: { $ne: t._id } },
{ $inc: { balance: t.value }, $push: { pendingTransactions: t._id } }
)
4)Update transaction state to applied
db.transactions.update(
{ _id: t._id, state: "pending" },
{
$set: { state: "applied" },
$currentDate: { lastModified: true }
}
)
5)Update both accounts list of pending transactions.
db.accounts.update(
{ _id: t.source, pendingTransactions: t._id },
{ $pull: { pendingTransactions: t._id } }
)
db.accounts.update(
{ _id: t.destination, pendingTransactions: t._id },
{ $pull: { pendingTransactions: t._id } }
)
6)Update transaction state to done.
db.transactions.update(
{ _id: t._id, state: "applied" },
{
$set: { state: "done" },
$currentDate: { lastModified: true }
}
)
0 Comment(s)