You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
InsertAsync / InsertBulkAsync / UpsertAsync roll back the caller's explicit transaction on any exception #185
DocumentCollection.InsertAsync, InsertBulkAsync and UpsertAsync roll back the transaction in their catch blocks even when the caller passed it in (DocumentCollection.cs ~L2028, ~L2084, ~L2961 on the #182 branch). UpdateAsync only rolls back a transaction it created itself (if (autoCommit)).
So any exception inside an explicit transaction aborts the whole transaction: a unique-index violation (#176), a serialization error, etc. The caller can't catch the error and carry on, and the next CommitAsync fails with "state Aborted".
Repro
awaitpeople.CreateIndexAsync(p =>p.Name,"idx_name",unique:true);usingvartx=awaitdb.BeginTransactionAsync();awaitpeople.InsertAsync(newPerson{Name="a"},tx);try{awaitpeople.InsertAsync(newPerson{Name="a"},tx);}catch(InvalidOperationException){/* expected duplicate */}awaittx.CommitAsync();// throws: transaction is Aborted; the first insert is lost
Expected: these methods behave like UpdateAsync. They roll back only a transaction they own; otherwise they rethrow and leave the caller's transaction as it was. With #182, a rejected write leaves no pages behind, because the unique check runs before any write.
Whether a failed operation should poison a caller-owned transaction is a design choice, but it should be the same for Insert, Update and Upsert.
Activity
fix(collections): validate writes up front, roll back after a mid-wri…
test(index): expect BLiteValidationException for unique violations in…
fix(collections): don't roll back a caller-owned transaction on a fai…