|
|
@@ -187,12 +187,15 @@ if (result) {
|
|
|
std::cout << (*result)["name"] << std::endl;
|
|
|
}
|
|
|
|
|
|
-// Update
|
|
|
-db.update("users", "user-123", {{"name", "Alice Smith"}});
|
|
|
+// Update (full document replacement, with automatic optimistic locking)
|
|
|
+db.update("users", "user-123", {{"name", "Alice Smith"}, {"email", "alice@example.com"}});
|
|
|
|
|
|
-// Update with optimistic locking (fails if version changed)
|
|
|
+// Update with explicit optimistic locking (fails if version changed)
|
|
|
db.updateIfVersion("users", "user-123", {{"name", "Alice"}}, /*expectedVersion=*/2);
|
|
|
|
|
|
+// Patch — atomic partial update (only specified fields are modified)
|
|
|
+uint64_t newVer = db.patch("users", "user-123", {{"name", "Alice Smith"}});
|
|
|
+
|
|
|
// Upsert (insert or update)
|
|
|
auto [uid, isNew] = db.upsert("users", doc, "user-123");
|
|
|
|
|
|
@@ -203,6 +206,42 @@ db.remove("users", "user-123");
|
|
|
bool found = db.exists("users", "user-123");
|
|
|
```
|
|
|
|
|
|
+### Concurrency: update() vs patch()
|
|
|
+
|
|
|
+When multiple clients modify the same document concurrently, choose the right method:
|
|
|
+
|
|
|
+**`patch()`** — use for most updates (recommended). Merges only the specified fields on the server, atomically. Two clients can safely modify different fields simultaneously:
|
|
|
+
|
|
|
+```cpp
|
|
|
+// Client A: // Client B:
|
|
|
+db.patch("users", "user-123", db.patch("users", "user-123",
|
|
|
+ {{"name", "Alice Smith"}}); {{"email", "alice@new.com"}});
|
|
|
+// Result: both fields updated, nothing lost
|
|
|
+```
|
|
|
+
|
|
|
+**`update()`** — full document replacement with automatic retry. Uses optimistic locking internally (reads current version, writes with version check, retries on conflict). Use when you need to replace the entire document:
|
|
|
+
|
|
|
+```cpp
|
|
|
+auto doc = db.get("users", "user-123");
|
|
|
+(*doc)["name"] = "Alice Smith";
|
|
|
+(*doc)["role"] = "admin";
|
|
|
+db.update("users", "user-123", *doc); // replaces entire document
|
|
|
+```
|
|
|
+
|
|
|
+Note: `update()` is "last writer wins" for complete replacement — if two clients modify different fields via `update()`, the last one overwrites the other's changes. Use `patch()` to avoid this.
|
|
|
+
|
|
|
+**`updateIfVersion()`** — explicit optimistic locking. Use when you need to detect conflicts and handle them yourself:
|
|
|
+
|
|
|
+```cpp
|
|
|
+auto doc = db.get("users", "user-123");
|
|
|
+uint64_t version = (*doc)["_version"];
|
|
|
+(*doc)["balance"] = (*doc)["balance"].get<int>() + 100;
|
|
|
+if (!db.updateIfVersion("users", "user-123", *doc, version)) {
|
|
|
+ // Version conflict — someone else modified the document
|
|
|
+ // Re-read and retry, or report error to user
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
### Querying
|
|
|
|
|
|
```cpp
|