[ 
https://issues.apache.org/jira/browse/IBATISNET-212?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Gilles Bayon closed IBATISNET-212.
----------------------------------

       Resolution: Fixed
    Fix Version/s: DataMapper 1.6.1
         Assignee: Gilles Bayon

In SVN, renames property as IsTransactionStart

> Add the ability to track Open Transactions via IDalSession
> ----------------------------------------------------------
>
>                 Key: IBATISNET-212
>                 URL: https://issues.apache.org/jira/browse/IBATISNET-212
>             Project: iBatis for .NET
>          Issue Type: Improvement
>          Components: DataMapper
>         Environment: Any
>            Reporter: Samuel Clough
>         Assigned To: Gilles Bayon
>             Fix For: DataMapper 1.6.1
>
>         Attachments: IDalSession.cs, SqlMapSession.cs
>
>
> At times, a method call may need to call another method call as part of one 
> logical data insert/update operation.  Currently the problem is that iBatis 
> does not expose in the session interface whether or not their is an open 
> transaction.  Because of this, a method that may be called as part of a 
> larger data update has no way of checking to see if a transaction is open 
> before opening another one.  Some RDMSs allow nested transactions and this is 
> not a problem, but other providers do not and it can become a problem.  The 
> suggestion is that iBatis expose the _isOpenTransaction field on the session 
> via a property so that it can be checked in a method call when a method needs 
> to determine if it should open a transaction or not.  
> Below is a sample use case where ObjectB can be updated, but ObjectB is also 
> a property of ObjectA and when ObjectA is updated, the embedded ObjectB 
> should be updated as well all within one transaction.  (This is just an 
> example, not great code).
> class Example
> {
>     private ISqlMapper _mapper = null;
>     
>     public Example()
>     {
>         _mapper = Mapper.Instance();
>     }
>     public void UpdateA(ObjectA a)
>     {
>         _dataMapper.StartTransaction();
>         _dataMapper.update("update-a", a);
>         UpdateB(a.ObjectB);
>         _dataMapper.CommitTransaction();
>     }
>     public void UpdateB(ObjectB b)
>     {
>         bool existingTransaction = _dataMapper.TransactionOpen;
>         if (!existingTransaction)
>         {
>             _dataMapper.StartTransaction();
>         }
>         _dataMapper.Update("update-b", b);
>         if (!existingTransaction)
>         {
>             _dataMapper.CommitTransaction();
>         }
>     }
> }
> This has been a major need for us on some projects and I would suppose for 
> others as well.  For that reason, we are proposing this enhancement rather 
> than creating some in house solution or a custom iBatis build.  In order to 
> make the changes, the following changes would need to be made to the code:
> The IBatisNet.Common.IDalSession interface would need the following new 
> property:
> bool OpenTransaction{ get; }
> The IBatisNet.DataMapper.SqlMapSession would need the following changes:
> 1.  Implement the new property to expose the existing field.:
> public bool OpenTransaction
> {
>      get { return _isOpenTransaction; }
> }
> 2. Update the CommitTransaction methods to be as follows including an update 
> to the _isOpenTransaction field:
>               /// <summary>
>               /// Commits the database transaction.
>               /// </summary>
>               /// <remarks>
>               /// Will close the connection.
>               /// </remarks>
>               public void CommitTransaction()
>               {
>                       if (_logger.IsDebugEnabled)
>                       {
>                               _logger.Debug("Commit Transaction.");
>                       }
>                       _transaction.Commit();
>                       _transaction.Dispose();
>                        _isOpenTransaction = false;
>                       if (_connection.State != ConnectionState.Closed)
>                       {
>                               this.CloseConnection();
>                       }
>               }
>               /// <summary>
>               /// Commits the database transaction.
>               /// </summary>
>               /// <param name="closeConnection">Close the connection</param>
>               public void CommitTransaction(bool closeConnection)
>               {
>                       if (closeConnection)
>                       {
>                               this.CommitTransaction();
>                       }
>                       else
>                       {
>                               _transaction.Commit();
>                               if (_logger.IsDebugEnabled)
>                               {
>                                       _logger.Debug("Commit Transaction.");
>                               }
>                               _transaction.Dispose();
>                                _isOpenTransaction = false;
>                       }
>               }
> 3.  Update the RollbackTransaction methods to set the state of the 
> _isOpenTransaction field as follows:
>               /// <summary>
>               /// Rolls back a transaction from a pending state.
>               /// </summary>
>               /// <remarks>
>               /// Will close the connection.
>               /// </remarks>
>               public void RollBackTransaction()
>               {
>                       _transaction.Rollback();
>                       if (_logger.IsDebugEnabled)
>                       {
>                               _logger.Debug("RollBack Transaction.");
>                       }
>                       _transaction.Dispose();
>                       _transaction = null;
>                        _isOpenTransaction = false;
>                       if (_connection.State != ConnectionState.Closed)
>                       {
>                               this.CloseConnection();
>                       }
>               }
>               /// <summary>
>               /// Rolls back a transaction from a pending state.
>               /// </summary>
>               /// <param name="closeConnection">Close the connection</param>
>               public void RollBackTransaction(bool closeConnection)
>               {
>                       if (closeConnection)
>                       {
>                               this.RollBackTransaction();
>                       }
>                       else
>                       {
>                               if (_logger.IsDebugEnabled)
>                               {
>                                       _logger.Debug("RollBack Transaction.");
>                               }
>                               _transaction.Rollback();
>                               _transaction.Dispose();
>                               _transaction = null;
>                                 _isOpenTransaction = false;
>                       }
>               }
> This would be very helpful when developing against RDMS servers and/or 
> providers that do not support nested transactions as well as be more 
> efficient than nested transactions.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to