Jan Blaha

Blog about software development

Run action after transaction commit using NHibernate

.NET NHibernate

Problem

One of the session/transaction handling technique in NHibernate is called session/transaction per request. The name of this technique is self explanatory. You open a transaction and session when request comes to the application and commits and dispose transaction at the end of the request. This is very popular for web applications where you expect short running requests. This makes the development easier since you don't need to care about the session and transaction scopes. But there are cases where you actually care about the transaction scope and want to invoke some custom action after the transaction is committed. This can be for example submitting a message to azure service bus or calling another system. You can oppose that you should employ distributed transactions for this. But actually azure sevice bus for example does not support DTS and in many other cases it's just not necessary and overhead using DTS.

Implementation

You can use http context to store an information what you want to do at the end of the request but this is just ugly and better is to use what NHibernate offers. NHibernate Transaction class exposes method RegisterSynchronization. This method can be used to register for transaction events and accepts implementation of ISynchronization interface. You only need to implement methods BeforeCompletion and AfterCompletion and you are done.

Basic implementation of ISynchronization invoking custom action after transaction commit can look following:

public class TransactionSynchronization : ISynchronization
{
    private readonly Action _action;

    public TransactionSynchronization(Action action)
    {
        _action = action;
    }

    public void BeforeCompletion()
    {

    }

    public void AfterCompletion(bool success)
    {
        if (success)
            _action();
    }
}

When you have TransactionSynchronization you can just call RegisterSynchronization and register any custom action you want.

Session.Transaction.RegisterSynchronization(new ThreadSynchronization(() => {
    var client = new HttpClient()
    ...
}));

last blog posts


09-12-2017 18:40 jsreport

Quite some time ago I blogged about rendering pdf reports in c#. Recently we have added excel reports into jsreport and it was released with a little delay also into .NET. This means you should be able to use both html-to-xlsx and xlsx recipes to create excel files from your .NET environments now.

read more

09-10-2015 14:09 AWS

Such a very common thing like adding an existing external volume to Amazon elastic beanstalk is not easily supported out of the box. The official blog mentions only how to attach a snapshot or how to attach and overwrite a new volume every time the service starts. It took me a while to make the config file actually adding an existing volume without formatting it every time so I share it here with you...

read more

04-10-2015 14:09 jsreport

The best practice when adding email notifications feature to your system is to separate as much as you can from email body assembling to email sending outside of the core system. The emails templates quite likely often changes and you don't want to deploy the system because of every single notification change. The best is to just separate everything into an external system and give the access to your PR or Marketing department so they change emails as the time goes without affecting the core system.

read more

Jan Blaha

About author

Hi! My name is Jan Blaha. I'm software developer and startup enthusiastic. See my current work.