3. • 15+ years building the
internet
• Father, husband, skateboarder
• Chief Solutions Architect @
10gen
• Author of upcoming O’Reilly
publication
“MongoDB and PHP”
21. MongoDB philosophy
• Keep functionality when we can (key/
value stores are great, but we need more)
• Non-relational (no joins) makes scaling
horizontally practical
• Document data models are good
• Database technology should run
anywhere VMs, cloud, metal, etc
22. MongoDB is:
Application Document
Oriented
{ author: “steve”,
High date: new Date(),
text: “About MongoDB...”,
Performance tags: [“tech”, “database”]}
Fully
Consistent
Horizontally Scalable
23. Under the hood
•Written in C++
•Runs on nearly anything
•Data serialized to BSON
•Extensive use of memory-mapped files
27. CMS / Blog
Needs:
• Business needed modern data store for rapid development and
scale
Solution:
• Use PHP & MongoDB
Results:
• Real time statistics
• All data, images, etc stored together, easy access, easy
deployment, easy high availability
• No need for complex migrations
• Enabled very rapid development and growth
28. Photo Meta-Data
Problem:
• Business needed more flexibility than Oracle could deliver
Solution:
• Use MongoDB instead of Oracle
Results:
• Developed application in one sprint cycle
• 500% cost reduction compared to Oracle
• 900% performance improvement compared to Oracle
29. Customer Analytics
Problem:
• Deal with massive data volume across all customer sites
Solution:
• Use MongoDB to replace Google Analytics / Omniture options
Results:
• Less than one week to build prototype and prove business case
• Rapid deployment of new features
30. Online Dictionary
Problem:
• MySQL could not scale to handle their 5B+ documents
Solution:
• Switched from MySQL to MongoDB
Results:
• Massive simplification of code base
• Eliminated need for external caching system
• 20x performance improvement over MySQL
31. E-commerce
Problem:
• Multi-vertical E-commerce impossible to model (efficiently) in
RDBMS
Solution:
• Switched from MySQL to MongoDB
Results:
• Massive simplification of code base
• Rapidly build, halving time to market (and cost)
• Eliminated need for external caching system
• 50x+ improvement over MySQL
40. Let’s Use an Example
How about we start with books
41. Book Product Schema
Product {
id:
sku: General Product
product dimensions:
shipping weight:
attributes
MSRP:
price:
description:
...
author: Orson Scott Card
title: Enders Game
binding: Hardcover
publication date: July 15, 1994 Book Specific
publisher name: Tor Science Fiction attributes
number of pages: 352
ISBN: 0812550706
language: English
...
43. Album Product Schema
Product {
id:
sku: General Product
product dimensions: attributes stay
shipping weight:
MSRP:
the same
price:
description:
...
artist: MxPx
title: Panic Album Specific
release date: June 7, 2005
label: Side One Dummy
attributes are
track listing: [ The Darkest ... different
language: English
format: CD
...
44. Okay, it’s getting
hairy but is still
manageable, right?
Now the business want to sell jeans
45. Jeans Product Schema
Product {
id: General Product
sku: attributes stay the
product dimensions: same
shipping weight:
MSRP:
price:
description:
...
brand: Lucky Jeans specific
gender: Mens attributes are
make: Vintage
totally different ...
style: Straight Cut
length: 34 and not consistent
width: 34 across brands &
color: Hipster
make
material: Cotten Blend
...
52. EAV
as popularized by Magento
“For purposes of flexibility, the Magento database heavily
utilizes an Entity-Attribute-Value (EAV) data model.
As is often the case, the cost of flexibility is complexity -
Magento is no exception.
The process of manipulating data in Magento is often
more “involved” than that typically experienced using
traditional relational tables.”
- Varien
53. EAV
• Crazy SQL queries
• Hundreds of joins in a
query... or
• Hundreds of queries joined
in the application
• No database enforced
integrity
57. Single Table Inheritance
(insanely wide tables)
• No data integrity enforcement
• Only can use FK for common
elements
• Very wasteful (but disk is
cheap!)
• Can’t effectively index
58. Generic Columns
• No data integrity enforcement
• No data type enforcement
• Only can use FK for common
elements
• Wasteful (but disk is cheap!)
• Can’t index
59. Serialized in Blob
• Not searchable
• No integrity
• All the disadvantages of a
document store, but none of the
advantages
• Never should be used
• One exception is Oracle XML
which operates similar to a
document store
60. Concrete Table Inheritance
(a table for each product attribute set)
• Allows for data integrity
• Querying across attribute
sets quite hard to do (lots
of joins, OR statements
and full table scanning)
• New table needs to be
created for each new
attribute set
61. Class table inheritance
(single product table,
each attribute set in own table)
• Likely best of SQL within the
constraint
solution
• Supports data type enforcement
• No data integrity enforcement
• Easybrowse pages) since
(for
querying across categories
common data in single table
• Every set needs a new table
• Requiresare very complicated
changes
a ton of forsight, as
79. Wanna Play?
• grab products.js from
http://github.com/spf13/
mongoProducts
• mongo --shell products.js
• > use mongoProducts
80. Embedded documents
are great for orders
•Ordered items need to be fixed at the
time of purchase
•Embed them right in the order
db.order.find( { 'items.sku': '00e8da9f' } );
db.order.find( {
'items.details.actor': 'James Stewart'
} ).count();
81. What about
transactions?
Using the right solution for each situation
99. Isolation
• // Pseudo-isolated updates
db.foo.update( { x : 1 } , { $inc : { y : 1 } } , false , true );
• // Isolated updates
db.foo.update( { x : 1 , $atomic : 1 } , { $inc : { y : 1 } } , false ,
true );
• But there are caveats...
100. Isolation
• // Pseudo-isolated updates
db.foo.update( { x : 1 } , { $inc : { y : 1 } } , false , true );
• // Isolated updates
db.foo.update( { x : 1 , $atomic : 1 } , { $inc : { y : 1 } } , false ,
true );
• But there are caveats...
• Despite the $atomic keyword, this is not an atomic update,
since atomicity implies “all or nothing”
101. Isolation
• // Pseudo-isolated updates
db.foo.update( { x : 1 } , { $inc : { y : 1 } } , false , true );
• // Isolated updates
db.foo.update( { x : 1 , $atomic : 1 } , { $inc : { y : 1 } } , false ,
true );
• But there are caveats...
• Despite the $atomic keyword, this is not an atomic update,
since atomicity implies “all or nothing”
• $atomic here means update is done without an interference
from any other operation (isolated)
102. Isolation
• // Pseudo-isolated updates
db.foo.update( { x : 1 } , { $inc : { y : 1 } } , false , true );
• // Isolated updates
db.foo.update( { x : 1 , $atomic : 1 } , { $inc : { y : 1 } } , false ,
true );
• But there are caveats...
• Despite the $atomic keyword, this is not an atomic update,
since atomicity implies “all or nothing”
• $atomic here means update is done without an interference
from any other operation (isolated)
• An isolated update can only act on a single collection. Multi-
collection updates are not transactional, thus not
isolatable.
107. • Atomic single document writes
• If you need atomic writes across multi-document
transactions don't use Mongo
• Many if not most e-commerce transactions could be
accomplished within a single document write
108. • Atomic single document writes
• If you need atomic writes across multi-document
transactions don't use Mongo
• Many if not most e-commerce transactions could be
accomplished within a single document write
• Unique indexes
• This only works on keys used by the entire
collection
109. • Atomic single document writes
• If you need atomic writes across multi-document
transactions don't use Mongo
• Many if not most e-commerce transactions could be
accomplished within a single document write
• Unique indexes
• This only works on keys used by the entire
collection
• Isolated (not atomic) single collection updates.
• Mongo does not support locking
• There are ways to work around this
110. • Atomic single document writes
• If you need atomic writes across multi-document
transactions don't use Mongo
• Many if not most e-commerce transactions could be
accomplished within a single document write
• Unique indexes
• This only works on keys used by the entire
collection
• Isolated (not atomic) single collection updates.
• Mongo does not support locking
• There are ways to work around this
• It’s durable
111. There are ways to
guarantee ACID
properties in MongoDB
Here are 2 good approaches useful for
E-commerce transactions
113. Optimistic
Concurrency
•Read the current state of a product
114. Optimistic
Concurrency
•Read the current state of a product
•Make your changes with the assertion
that your product has the same state as
it did when you last read it
117. Optimistic concurrency
in MongoDB
We’ll use an update-if-current strategy.
This example is straight from the documentation:
118. Optimistic concurrency
in MongoDB
We’ll use an update-if-current strategy.
This example is straight from the documentation:
> t = db.inventory
> p = t.findOne({sku:'abc'})
> t.update({_id:p._id, qty:p.qty}, {'$inc': {qty: -1}});
> db.$cmd.findOne({getlasterror:1});
{"err" : , "updatedExisting" : true , "n" : 1 , "ok" : 1}
// it worked
119. Optimistic concurrency
in MongoDB
We’ll use an update-if-current strategy.
This example is straight from the documentation:
> t = db.inventory
> p = t.findOne({sku:'abc'})
> t.update({_id:p._id, qty:p.qty}, {'$inc': {qty: -1}});
> db.$cmd.findOne({getlasterror:1});
{"err" : , "updatedExisting" : true , "n" : 1 , "ok" : 1}
// it worked
... If that didn't work, try again until it does.
120. Optimistic
concurrency
•Read the current state of a product.
•Make your changes with the assertion
that your product has the same state as
it did when you last read it.
121. Optimistic
concurrency
•Read the current state of a product.
•Make your changes with the assertion
that your product has the same state as
it did when you last read it.
• It is also possible to use OCC to
bootstrap pessimistic concurrency and
fake row level locking
123. OCC works great for
companies like Amazon
•Amazon has a long-tail catalog
•A long tail catalog lends itself well to
optimistic concurrency, because it has
low data contention
133. Flash sales and
auctions are defined by
high data contention
•The model doesn't work otherwise
•They can't afford to be optimistic
134. Flash sales and
auctions are defined by
high data contention
•The model doesn't work otherwise
•They can't afford to be optimistic
•Order really matters
139. 1. I go to Barneys and see a pair of shoes I just have to
buy.
2. I call “dibs” (by grabbing them off the shelf).
3. I take them up to the cash register and purchase
them:
• Store inventory has been manually decremented.
• I pay for them with my trusty AmEx.
4. If all goes according to plan, I walk out of the store.
5. If my card was declined, the shoes are “rolled back”
... out onto the shelves and sold to the next customer
who wants them.
140. All of this is
accomplished
without concurrency
145. 1. Select a product.
2. Update the document to hold inventory.
146. 1. Select a product.
2. Update the document to hold inventory.
• Store inventory has been
decremented.
147. 1. Select a product.
2. Update the document to hold inventory.
• Store inventory has been
decremented.
3. Purchase the product(s)
148. 1. Select a product.
2. Update the document to hold inventory.
• Store inventory has been
decremented.
3. Purchase the product(s)
• Process payment
149. 1. Select a product.
2. Update the document to hold inventory.
• Store inventory has been
decremented.
3. Purchase the product(s)
• Process payment
4. Roll back if anything went wrong.
151. MongoDB e-commerce
transactions
• Each Item (not SKU) has it’s own document
• Document consists of...
• a reference to the SKU (product)
• a state ( available / sold / ... )
• potentially other data (timestamp, order
ref)
153. Transactions
in MongoDB
We’ll use a simple update statement
here.
154. Transactions
in MongoDB
We’ll use a simple update statement
here.
> t = db.inventory
> sku = sku.findOne({sku:'abc'})
> t.update({ref_id:sku._id, state: 'available'}, {'$set':
{state: 'ordered'}});
> db.$cmd.findOne({getlasterror:1});
{"err" : , "updatedExisting" : true , "n" : 1 , "ok" : 1}
// it worked
155. Transactions
in MongoDB
We’ll use a simple update statement
here.
> t = db.inventory
> sku = sku.findOne({sku:'abc'})
> t.update({ref_id:sku._id, state: 'available'}, {'$set':
{state: 'ordered'}});
> db.$cmd.findOne({getlasterror:1});
{"err" : , "updatedExisting" : true , "n" : 1 , "ok" : 1}
// it worked
... If that didn't work, no inventory available
157. Cart in Cart Action
An added benefit, it can easily provide
inventory hold in cart.
158. Cart in Cart Action
An added benefit, it can easily provide
inventory hold in cart.
> t = db.inventory
> sku = sku.findOne({sku:'abc'})
> t.update({ref_id:sku._id, state: 'available'}, {'$set':
{state: 'in cart'}});
> db.$cmd.findOne({getlasterror:1});
{"err" : , "updatedExisting" : true , "n" : 1 , "ok" : 1}
// it worked
159. Cart in Cart Action
An added benefit, it can easily provide
inventory hold in cart.
> t = db.inventory
> sku = sku.findOne({sku:'abc'})
> t.update({ref_id:sku._id, state: 'available'}, {'$set':
{state: 'in cart'}});
> db.$cmd.findOne({getlasterror:1});
{"err" : , "updatedExisting" : true , "n" : 1 , "ok" : 1}
// it worked
just like reality, each item is either
available, in a cart, or purchased
160. http://spf13.com
http://github.com/spf13
@spf13
Questions?
download at mongodb.org
PS: We’re hiring!! Contact us at jobs@10gen.com
Notes de l'éditeur
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Remember in 1995 there were around 10,000 websites. Mosiac, Lynx, Mozilla (pre netscape) and IE 2.0 were the only web browsers. \nApache (Dec ’95), Java (’96), PHP (June ’95), and .net didn’t exist yet. Linux just barely (1.0 in ’94)\n
Remember in 1995 there were around 10,000 websites. Mosiac, Lynx, Mozilla (pre netscape) and IE 2.0 were the only web browsers. \nApache (Dec ’95), Java (’96), PHP (June ’95), and .net didn’t exist yet. Linux just barely (1.0 in ’94)\n
Remember in 1995 there were around 10,000 websites. Mosiac, Lynx, Mozilla (pre netscape) and IE 2.0 were the only web browsers. \nApache (Dec ’95), Java (’96), PHP (June ’95), and .net didn’t exist yet. Linux just barely (1.0 in ’94)\n
\n
\n
\n
\n
By reducing transactional semantics the db provides, one can still solve an interesting set of problems where performance is very important, and horizontal scaling then becomes easier.\n\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
actually, just the first 1/3 of it. \n
\n
Ironically this is how magento solves the performance problems associated with EAV, by caching the data into insanely wide tables.\n
\n
\n
\n
Can’t create a FK as each set references a different table. “Key” really made of attribute table name id and attribute table name\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Whenever you use a inter system coordination you need to implement your own atomic checks in the application... But SOAP does have transactions.. so not quite accurate. \n\nkyle idea... but we are fairly atomic with authorize.net\n\natomicity, consistency, isolation, durability.\n\n
Whenever you use a inter system coordination you need to implement your own atomic checks in the application... But SOAP does have transactions.. so not quite accurate. \n\nkyle idea... but we are fairly atomic with authorize.net\n\natomicity, consistency, isolation, durability.\n\n
Mongo has a grip of atomic operations: set, unset, etc.\n
Mongo has a grip of atomic operations: set, unset, etc.\n
Mongo has a grip of atomic operations: set, unset, etc.\n
\n
\n
update( { where }, { values }, upsert?, multiple? )\n\nIsolated is not atomic. Atomic implies that there is an all-or-nothing semantic to the update; this is not possible with more than one document. Isolated just means than you are the only one writing when the update is done; this means each update is done without any interference from any other.\n\nMongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n\n\n
update( { where }, { values }, upsert?, multiple? )\n\nIsolated is not atomic. Atomic implies that there is an all-or-nothing semantic to the update; this is not possible with more than one document. Isolated just means than you are the only one writing when the update is done; this means each update is done without any interference from any other.\n\nMongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n\n\n
update( { where }, { values }, upsert?, multiple? )\n\nIsolated is not atomic. Atomic implies that there is an all-or-nothing semantic to the update; this is not possible with more than one document. Isolated just means than you are the only one writing when the update is done; this means each update is done without any interference from any other.\n\nMongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n\n\n
update( { where }, { values }, upsert?, multiple? )\n\nIsolated is not atomic. Atomic implies that there is an all-or-nothing semantic to the update; this is not possible with more than one document. Isolated just means than you are the only one writing when the update is done; this means each update is done without any interference from any other.\n\nMongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n\n\n
update( { where }, { values }, upsert?, multiple? )\n\nIsolated is not atomic. Atomic implies that there is an all-or-nothing semantic to the update; this is not possible with more than one document. Isolated just means than you are the only one writing when the update is done; this means each update is done without any interference from any other.\n\nMongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n\n\n
update( { where }, { values }, upsert?, multiple? )\n\nIsolated is not atomic. Atomic implies that there is an all-or-nothing semantic to the update; this is not possible with more than one document. Isolated just means than you are the only one writing when the update is done; this means each update is done without any interference from any other.\n\nMongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n\n\n
\n
\n
MongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n
MongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n
MongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n
MongoDB supports atomic operations on single documents.  MongoDB does not support traditional locking and complex transactions for a number of reasons:\nFirst, in sharded environments, distributed locks could be expensive and slow.  Mongo DB's goal is to be lightweight and fast.\nWe dislike the concept of deadlocks.  We want the system to be simple and predictable without these sort of surprises.\nWe want Mongo DB to work well for realtime problems.  If an operation may execute which locks large amounts of data, it might stop some small light queries for an extended period of time.  (We don't claim Mongo DB is perfect yet in regards to being "real-time", but we certainly think locking would make it even harder.)\n\n
\n
lemme show you an example\n
lemme show you an example\n
or instead of qty, use an version_id.\n object id / md5 as a version. \n
or instead of qty, use an version_id.\n object id / md5 as a version. \n
or instead of qty, use an version_id.\n object id / md5 as a version. \n
or instead of qty, use an version_id.\n object id / md5 as a version. \n
\n
Imagine what would happen if everyone tried to access the same record at the same time. Just think of all those spinning while loops :)\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Mind if I tell you a story?\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
By using a single document we avoid any need for complicated transactions. \n Any number of concurrent read operations are allowed, but typically only one write operation (although some write operations yield and in the future more concurrency will be added). The write lock acquisition is greedy: a pending write lock acquisition will prevent further read lock acquisitions until fulfilled.\n
By using a single document we avoid any need for complicated transactions. \n Any number of concurrent read operations are allowed, but typically only one write operation (although some write operations yield and in the future more concurrency will be added). The write lock acquisition is greedy: a pending write lock acquisition will prevent further read lock acquisitions until fulfilled.\n
By using a single document we avoid any need for complicated transactions. \n Any number of concurrent read operations are allowed, but typically only one write operation (although some write operations yield and in the future more concurrency will be added). The write lock acquisition is greedy: a pending write lock acquisition will prevent further read lock acquisitions until fulfilled.\n
By using a single document we avoid any need for complicated transactions. \n Any number of concurrent read operations are allowed, but typically only one write operation (although some write operations yield and in the future more concurrency will be added). The write lock acquisition is greedy: a pending write lock acquisition will prevent further read lock acquisitions until fulfilled.\n
By using a single document we avoid any need for complicated transactions. \n Any number of concurrent read operations are allowed, but typically only one write operation (although some write operations yield and in the future more concurrency will be added). The write lock acquisition is greedy: a pending write lock acquisition will prevent further read lock acquisitions until fulfilled.\n
By using a single document we avoid any need for complicated transactions. \n Any number of concurrent read operations are allowed, but typically only one write operation (although some write operations yield and in the future more concurrency will be added). The write lock acquisition is greedy: a pending write lock acquisition will prevent further read lock acquisitions until fulfilled.\n
\n
\n
\n
\n
\n
Inventory can be provided by using count. Can be cached as value on the sku.\nAs the items themselves are atomic, the order need not be to reserve inventory.\n
Inventory can be provided by using count. Can be cached as value on the sku.\nAs the items themselves are atomic, the order need not be to reserve inventory.\n
Inventory can be provided by using count. Can be cached as value on the sku.\nAs the items themselves are atomic, the order need not be to reserve inventory.\n
remember by default, update only updates 1 document and the operation is atomic on that document.\n\n
remember by default, update only updates 1 document and the operation is atomic on that document.\n\n
remember by default, update only updates 1 document and the operation is atomic on that document.\n\n