A Simple Closure To Handle Try/Catch Around Transactions


(Updated: I moved the begin transaction outside of the try as Chad suggested in the comments.)

If you’re like me, you’re lazy and hate putting try/catch around your transaction handling in your code. It has to be there, but it’s just a pain. You may have code that looks something like:

domainContext.BeginTransaction();

try
{
    historicalPwdService.RecordHistoricalPassword(user.UserProfileID, currentPassword);

    user.Password = newPassword;
    user.PasswordCreateDate = systemClock.Now();

    userProfileRepo.Save(user);

    domainContext.CommitTransaction();
}
catch
{
    domainContext.RollbackTransaction();
    throw;
}

Well here’s a little helper class that can ease the pain a bit:

public static class WorkUnit
{
    public static void Do(IDomainContext context, Action workUnit)
    {
        context.BeginTransaction();

        try
        {
            workUnit();
                
            context.CommitTransaction();
        }
        catch
        {
            context.RollbackTransaction();

            throw;
        }
    }
}

now you can use it with an anonymous method:

WorkUnit.Do(domainContext, ()=>
    {
        historicalPwdService.RecordHistoricalPassword(user.UserProfileID, currentPassword);

        user.Password = newPassword;
        user.PasswordCreateDate = systemClock.Now();

        userProfileRepo.Save(user);
    });

Side note for Jimmy: You should be proud. I went back and switched out my custom delegate for Action. 😉

Technorati Tags: ,
Mapping Timestamp Data Using NHibernate’s ICompositeUserType