More explicit requirements regarding add_version

The core crate calls `get_client` and verifies the `latest_version_id`
before it invokes `add_version`. With the SQLite backend, transactions
lock the entire database, so these two queries cannot be interleaved
with any changes to the `latest_version_id` and there's no possibility
of incorrect updates. With Postgres (#129) the effect is similar: the
read performed by `get_client` locks that row and prevents other
transactions from writing to it.

However, the storage trait should not rely on this behavior --
`add_version` should verify that it is adding a new version on top of
the correct parent version.
This commit is contained in:
Dustin J. Mitchell 2025-07-13 13:04:03 -04:00
parent c539e604d9
commit 25911b44a6
No known key found for this signature in database
2 changed files with 60 additions and 16 deletions

View file

@ -37,7 +37,9 @@ pub struct Version {
///
/// Transactions must be sequentially consistent. That is, the results of transactions performed
/// in storage must be as if each were executed sequentially in some order. In particular,
/// un-committed changes must not be read by another transaction.
/// un-committed changes must not be read by another transaction, but committed changes must
/// be visible to subequent transations. Together, this guarantees that `add_version` reliably
/// constructs a linear sequence of versions.
///
/// Transactions with different client IDs cannot share any data, so it is safe to handle them
/// concurrently.
@ -70,8 +72,10 @@ pub trait StorageTxn {
async fn get_version(&mut self, version_id: Uuid) -> anyhow::Result<Option<Version>>;
/// Add a version (that must not already exist), and
/// - update latest_version_id
/// - update latest_version_id from parent_version_id to version_id
/// - increment snapshot.versions_since
/// Fails if the existing `latest_version_id` is not equal to `parent_version_id`. Check
/// this by calling `get_client` earlier in the same transaction.
async fn add_version(
&mut self,
version_id: Uuid,