Suppose I have the following methods in a service layer class:

public bool Update(User user)
{
 IBatisNet.DataMapper.Mapper.Instance().BeginTransaction();
 try
 {
  // do dao related things to Bar
  int bar = user.Bar;
  ProcessBar(bar);
  IBatisNet.DataMapper.Mapper.Instance().CommitTransaction();
  return true;
 }
 catch
 {
  IBatisNet.DataMapper.Mapper.Instance().RollbackTransaction();
  throw;
 }
}

public void ProcessBar(int bar)
{
 IBatisNet.DataMapper.Mapper.Instance().BeginTransaction();
 try
 {
  // snip
  IBatisNet.DataMapper.Mapper.Instance().CommitTransaction();
 }
 catch
 {
  IBatisNet.DataMapper.Mapper.Instance().RollbackTransaction();
  throw;
 }
}

Calling ProcessBar within Update will raise (as expected) an exception
of:

"
SqlMap could not invoke BeginTransaction(). A Transaction is already
started. Call CommitTransaction() or RollbackTransaction first.
"

How do I test if a transaction has already been started?

I saw this in SqlMapSession.cs:
 
 private bool _isOpenTransaction = false;

If that were a public property (added to IDalSession ???), I may be
able to write my own *Transaction methods like this:

// ???
protected virtual void BeginTransaction()
{
 if (IBatisNet.DataMapper.Mapper.Instance().IsOpenTransaction == false)
 {
  IBatisNet.DataMapper.Mapper.Instance().BeginTransaction();
 }
}

Then when I call ProcessBar, I shouldn't get the exception. 

I think I'm looking for some kind of "HasTransactionBeenStarted"
property.

I think this accomplishes the same thing without having to modify
anything:

 // ???
 protected virtual void BeginTransaction()
 {
  IDalSession session = Mapper.Instance().LocalSession;
  if (session.Transaction == null)
  {
   session.BeginTransaction();
  }
 }

Is there a better way to do all of this?

Thanks,
Ron

Reply via email to