Bulk variants of the write API not working with parent transaction

I have not been able to get any of the Db.*All methods from the API to work within a transaction. Looking at the source in OrmLiteWriteCommandExtensions.cs it appears that this should work.

I can’t tell why the transaction is not being passed through (and a new one is being created). The Db context is coming from the base ServiceStack.Service.

using (var tx = Db.BeginTransaction())
{
    var submission = Db.LoadSingleById<Submission>(request.Id);

    submission.PopulateWithNonDefaultValues(request.Form);

    Db.Delete<Meeting>(x => x.SubmissionId == submission.Id);
    Db.Delete<AuthorAffiliation>(x => x.SubmissionId == submission.Id);
    Db.Delete<Publication>(x => x.SubmissionId == submission.Id);

    Db.Save<Submission>(submission);

    if (submission.Meetings != null)
    {
        Db.SaveReferences(submission, submission.Meetings);

        var sponsors = submission.Meetings.SelectMany(m => {
            m.Sponsors?.Each(s => s.MeetingId = m.Id);
            return m.Sponsors ?? new List<MeetingOrganization>();
        });

        Db.SaveAll(sponsors);
    }

    if (submission.Publications != null)
    {
        Db.SaveReferences(submission, submission.Publications);
    }

    if (submission.AuthorAffiliations != null)
    {
        Db.SaveReferences(submission, submission.AuthorAffiliations);
    }

    tx.Commit();

    return submission.ToFormResponse();
}
System.InvalidOperationException: A transaction is already in progress; nested/concurrent transactions aren't supported.
   at Npgsql.NpgsqlConnection.BeginTransaction(IsolationLevel level)
   at Npgsql.NpgsqlConnection.BeginDbTransaction(IsolationLevel isolationLevel)
   at System.Data.Common.DbConnection.System.Data.IDbConnection.BeginTransaction()
   at ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.SaveAll[T](IDbCommand dbCmd, IEnumerable`1 objs) in C:\\BuildAgent\\work\\27e4cc16641be8c0\\src\\ServiceStack.OrmLite\\OrmLiteWriteCommandExtensions.cs:line 1003
   at ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.SaveReferences[T,TRef](IDbCommand dbCmd, T instance, TRef[] refs) in C:\\BuildAgent\\work\\27e4cc16641be8c0\\src\\ServiceStack.OrmLite\\OrmLiteWriteCommandExtensions.cs:line 1133
   at ServiceStack.OrmLite.OrmLiteWriteApi.<>c__DisplayClass40_0`2.<SaveReferences>b__0(IDbCommand dbCmd) in C:\\BuildAgent\\work\\27e4cc16641be8c0\\src\\ServiceStack.OrmLite\\OrmLiteWriteApi.cs:line 415
   at ServiceStack.OrmLite.OrmLiteExecFilter.Exec(IDbConnection dbConn, Action`1 filter) in C:\\BuildAgent\\work\\27e4cc16641be8c0\\src\\ServiceStack.OrmLite\\OrmLiteExecFilter.cs:line 94
   at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.Exec(IDbConnection dbConn, Action`1 filter) in C:\\BuildAgent\\work\\27e4cc16641be8c0\\src\\ServiceStack.OrmLite\\OrmLiteReadExpressionsApi.cs:line 22
   at ServiceStack.OrmLite.OrmLiteWriteApi.SaveReferences[T,TRef](IDbConnection dbConn, T instance, List`1 refs) in C:\\BuildAgent\\work\\27e4cc16641be8c0\\src\\ServiceStack.OrmLite\\OrmLiteWriteApi.cs:line 416
   at StrivesApi.ServiceInterface.SubmissionServices.Put(UpdateSubmissionRequest request) in /app/StrivesApi.ServiceInterface/SubmissionServices.cs:line 305
   at ServiceStack.Host.ServiceRunner`1.ExecuteAsync(IRequest req, Object instance, TRequest requestDto) in C:\\BuildAgent\\work\\3481147c480f4a2f\\src\\ServiceStack\\Host\\ServiceRunner.cs:line 133

Use OpenTransaction() as per the docs which also assigns it to the connection, e.g:

using var tx = Db.OpenTransaction();
1 Like