Reasoning
=========

I am in a somewhat ugly situation.

I have the need for a `DbTransaction`, wrapped around a "Plugin API" that potential Customers and other people have access to, allowing me to Rollback changes made to the database if something goes wrong (Aka: Exceptions happen).

I used to provide a single `DbContext` for this but that prooved challenging for more complex code, filling up the change tracker to quickly (which ment: performance drops, heavy memory usage etc.)

I switched over to a new design, allowing multiple DbContexts to run but now have the issue, that Entity Framework 6 with NPGSQL complains, the moment `DbContext.SaveChanges()` is called.

> 
> `A transaction is already in progress; nested/concurrent transactions aren't supported.`
> 
> 
> 
> ```
>   at Npgsql.NpgsqlConnection.BeginTransaction(IsolationLevel level)
>   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
>   at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.BeginTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
>   at System.Data.Entity.Core.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
> 
> ```
> 
> 

Simplified Example Code
=======================

```
// Example. Resides in another assembly
async Task Plugin(DbConnection dbConnection)
{
    using (var cntxt = new Database.Context(dbConnection))
    {
        cntxt.LogMessages.Add("Fancy Log Message");
        await cntxtb.SaveChangesAsync();
    }
}
// Simplified version of what actually happens
void PluginCaller()
{
    using var dbConnection = Database.Context.Connection(usereadonly: false);
    using var dbTransaction = dbConnection.BeginTransaction();
    Plugin(dbConnection).Wait();
}

```

The question now is
===================

How can i enforce a large transaction around whatever the plugins are doing to prevent a faulty plugin from corrupting the database (corrupting in this sense means: The next time the plugin runs, everything is fine but some items may be created twice now from the plugin, causing more errors)

Note:
=====

I already tried to use the `TransactionScope` for this but that yielded the same exception.