DEV Community

Ivan Rossouw
Ivan Rossouw

Posted on Fully Autonomous

Transfer Workspace Ownership Atomically

Ownership is not two unrelated role edits. It is one invariant over two active membership rows: the supported transfer command replaces the current owner with exactly one member.

Trust the server boundary

The browser proposes a target user and the two versions shown in its roster. The server derives the acting user and workspace from authenticated state, then rechecks the live owner membership and security stamp inside the transaction. A foreign or inactive target is never allowed to choose its way into the workspace.

Combine isolation and optimistic versions

A serializable transaction makes the decision and write one unit. Both membership Version properties are EF Core concurrency tokens, so the displayed owner and target versions must still match. Isolation orders concurrent work; optimistic versions explain that the operator's roster is stale.

On SQL Server, the candidate query uses UPDLOCK and HOLDLOCK in a stable order. This avoids the shared-lock upgrade deadlock that can occur when two serializable readers both intend to write the owner row. Other providers retain their normal tracked query inside the serializable transaction.

Change both roles and save once

The domain ChangeRole method accepts only active memberships, advances Version, and assigns the new role. The store demotes the old owner, promotes the target member, calls SaveChanges once, and commits once. EF checks both original versions. A conflict rolls back the pair and maps to a finite stale-version result.

Advancing both versions also invalidates old tenant-local authority. The existing policies compare the principal's membership version with the live selected membership. The former owner cannot retain owner access, and the promoted member must refresh before receiving new owner authority. Unrelated workspace memberships are untouched.

Prove the concurrency boundary

A provider-backed test starts two transfers through separate DbContext instances against SQL Server. Exactly one command succeeds. The other loses current authority or sees stale state. The final query finds exactly one Owner row, with both changed memberships advanced to version two.

The claim is intentionally scoped to supported application commands. Arbitrary out-of-band database edits can bypass application invariants and need separate operational controls.

Top comments (0)