Database Reference
In-Depth Information
someone must have removed that line item and we must try to
$push
it onto the array with its
new quantity:
def
def
increase_qty
(
order_id
,
sku
,
price
,
qty
):
total_update
=
price
*
qty
while
while
True
:
result
=
db
.
orders
.
update
(
{
'_id'
:
order_id
,
'items.sku'
:
sku
},
{
'$inc'
: {
'total'
:
total_update
,
'items.$.qty'
:
qty
} })
iif
result
[
'updatedExisting'
]:
break
break
result
=
db
.
orders
.
update
(
{
'_id'
:
order_id
,
'items.sku'
: {
'$ne'
:
sku
} },
{
'$inc'
: {
'total'
:
110.22
},
'$push'
: {
'items'
: {
'sku'
:
sku
,
'qty'
:
qty
,
'price'
:
price
} } })
iif
result
[
'updatedExisting'
]:
break
break
Optimistic Update with Compensation
There are some cases where it's just not possible to do your operation with a single
update()
statement in MongoDB. For instance, consider the account transfer problem where we must
debitoneaccount andcredit another.Inthesecases,wearestuckmakingmultiple updates,but
we must ensure that our database is eventually consistent by examining all the places where
we could have an error. A naive approach would simply store the account balance in each doc-
ument and update them separately. Our documents would be quite simple:
{
_id
:
1
,
balance
:
100
}
{
_id
:
2
,
balance
:
0
}
The code to update them is likewise simple:
def
def
transfer
(
amt
,
source
,
destination
):
result
=
db
.
accounts
.
update
(
{
'_id'
:
source
,
'balance'
: {
'$gte'
:
amt
} },
{
'$inc'
: {
'balance'
:
-
amt
} })
iif
not
not
result
[
'updatedExisting'
]:
raise
raise
InsufficientFundsError
(
source
)