generik0 / Smooth.IoC.Dapper.Repository.UnitOfWork

Smoother IoC using Dapper Dapper.FastCRUD with Repository and UnitOfWork patterns
MIT License
70 stars 26 forks source link

Db raise exception, commit executed on UnitOfWork dispose #14

Open janstupak opened 6 years ago

janstupak commented 6 years ago

Hi, situation:

using session created ... connection open inner using uow created ... begin transaction insert update insert ... throw exception dispose on uow call commit ... insert and update are commited !

this is not good transaction logic ... good transaction logic by me is "everything or nothing"

my workaround in DbTransaction.cs is little change in DisposeTransaction() method

    private void DisposeTransaction()
    {
        if (this.Transaction == null || this.Transaction.Connection == null) return;
        try
        {
            if (System.Runtime.InteropServices.Marshal.GetExceptionCode() == 0)
            {
                // commit only if no exception throws
                Commit();
            }
            else
            {
                Rollback();
            }
        }
        catch
        {
            Rollback();
            throw;
        }
        finally
        {
            if (this.Transaction != null)
            {
                this.Transaction.Dispose();
            }
            this.Transaction = null;
            factory.Release(this);
        }
    }

Jan

generik0 commented 6 years ago

Hi @janstupak I see your point.

I have always had:

using(var uow = db.UinitOfWork())
{
 try
  {
    //somehting thows
  }
catch(Exception exception)
  {
    uow.Rollback();
  }

}

I can add some virutals in the dispose methods if you like. Easier to substitute stuff. I am a little reluctant to use the runtime, or reflections to find out if there is an exception. Lets have a think about it.. Good point you have come with..., I have actually thought about it since the inception of the package. I have been waiting to do something with it, to see if it was a problem

generik0 commented 6 years ago

@janstupak Yeps. Looks like the Marshell is the only way to "sence" an exception. Interestingly though, What about if the exception should not rollback, and you want the data stored.. Think we need a switch for that. I agree with you that the default behavour should be exception = rollback.

janstupak commented 6 years ago

"I am a little reluctant to use the runtime, or reflections to find out if there is an exception." I am too, but in this situation is the only way ...

try/using ... session try/using ... uow try ... roll back if excetion

to many nested try's by me ... is not very clear ...

generik0 commented 6 years ago

@janstupak I agree with you. I will add the marshel and an option ASAP. Just need the time to do it :-) Thanks for the heads up..

janstupak commented 6 years ago

OK, thanks ... I waiting for new nuget package ... it's not urgent matter