0

ok, so Ayende recommends always using a transaction, even for read operations.
but supposing I have the following scenario:

public Employee GetEmployeeByName(string name)
        {
            using (ITransaction tx = CurrentSession.BeginTransaction())
            {
                return dao.GetEmployeeByName(name);
            }
        }

    public void SaveNewEmployee(Employee employee)
    {
        using (ITransaction tx = CurrentSession.BeginTransaction())
        {
            if (GetEmployeeByName(employee.Name) != null)
            {
                throw new ArgumentException("employee with same name found");
            }
            CurrentSession.Save(employee);
        }
    }

this would actually throw an exception, since nhibernate doesn't support nested transactions.
how can I get around this?

EDIT
this is even a better solution than the one I accepted...

Community
  • 1
  • 1
J. Ed
  • 6,692
  • 4
  • 39
  • 55

1 Answers1

2

Typically you would get around it by using a unit of work pattern in which you can start your transaction at the same time you open your session. That is to say at the beginning of the unit of work. And you would commit it at the end of the unit of work.

Vadim
  • 17,897
  • 4
  • 38
  • 62
  • sounds good. couple of questions: 1. There are requests where there is no db access (for example, I use 2nd level cache extensively). would your approach hurt performence for those cases? 2. When do I rollback a transaction? consider the two functions in my example. I would remove the transaction stuff, and add a try-catch block to each one. in the catch block I would roll the transaction back and continue throwing the exception. Now I have a problem where I rollback the transaction twice.. – J. Ed Jun 07 '11 at 06:39
  • @sJohnny, transactions are not costly so I wouldn't worry about it ([link](http://www.nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions)). As for 2, you would only need to rollback the transaction in the case of a write operation, so it only makes sense to rollback in SaveNewEmployee when you do a Save. – Vadim Jun 07 '11 at 14:23
  • the provided link doesn't state that transactions are inexpensive. it juts says that it's recommended to use them whenever you go to the db. my question was whether they should be used when no trip to the db is required, something that this post does not cover. as for 2- fair enough. But suppose that in the above example SaveNewEmployee also calls SaveNewBlahRecord? what then? – J. Ed Jun 09 '11 at 12:28
  • @sJhonny, "As previously mentioned, databases are always running in a transaction. Also, they have been heavily optimized to work with transactions." For your other question, I think your architecture may need some tweaking. If you want to expose all of these Save methods like that, but not control their entry points, then I would have your Save methods register an error on exception somewhere. Then in your Unit of work manager it can check if there were any errors and either commit or rollback the transaction. – Vadim Jun 09 '11 at 14:32