|
@@ -1493,6 +1493,16 @@ bool LmdbDocumentStore::del(WriteTxn& wtxn,
|
|
|
if (!cachedDbi(collection) && !known_this_txn) return false;
|
|
if (!cachedDbi(collection) && !known_this_txn) return false;
|
|
|
|
|
|
|
|
unsigned int dbi = open_for_write(wtxn, collection);
|
|
unsigned int dbi = open_for_write(wtxn, collection);
|
|
|
|
|
+ // Recorded immediately, not after mdb_del - see put(WriteTxn&, ...)'s
|
|
|
|
|
+ // comment. mdb_get (below) and maintainIndexes/maintainRelations can all
|
|
|
|
|
+ // throw (including UniqueViolation), and a throw between here and the
|
|
|
|
|
+ // old late emplace_back left the collection's own handle out of
|
|
|
|
|
+ // to_cache while any index/relation handles opened along the way were
|
|
|
|
|
+ // in it. Harmless for the no-txn wrapper above (its WriteTxn just aborts
|
|
|
|
|
+ // unwritten either way) but exactly Finding 2's shape one function over,
|
|
|
|
|
+ // and it becomes live the moment a cascade shares to_cache across calls,
|
|
|
|
|
+ // catches per-op exceptions, and commits the rest of the transaction.
|
|
|
|
|
+ to_cache.emplace_back(std::string(collection), dbi);
|
|
|
MDB_val k = to_val(id);
|
|
MDB_val k = to_val(id);
|
|
|
|
|
|
|
|
// Remove index entries before the row goes, while its stored bytes are
|
|
// Remove index entries before the row goes, while its stored bytes are
|
|
@@ -1515,9 +1525,8 @@ bool LmdbDocumentStore::del(WriteTxn& wtxn,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int rc = mdb_del(wtxn.raw(), dbi, &k, nullptr);
|
|
int rc = mdb_del(wtxn.raw(), dbi, &k, nullptr);
|
|
|
- // NOT cached here - the caller caches every entry in to_cache (this one
|
|
|
|
|
- // included) only after ITS commit succeeds.
|
|
|
|
|
- to_cache.emplace_back(std::string(collection), dbi);
|
|
|
|
|
|
|
+ // NOT cached here - the caller caches every entry in to_cache (recorded
|
|
|
|
|
+ // above) only after ITS commit succeeds.
|
|
|
if (rc == MDB_NOTFOUND) return false;
|
|
if (rc == MDB_NOTFOUND) return false;
|
|
|
if (rc != MDB_SUCCESS) throw_mdb(rc, "del");
|
|
if (rc != MDB_SUCCESS) throw_mdb(rc, "del");
|
|
|
return true;
|
|
return true;
|