You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ibatis.apache.org by "Gilles Bayon (JIRA)" <ib...@incubator.apache.org> on 2007/02/28 23:57:51 UTC

[jira] Closed: (IBATISNET-212) Add the ability to track Open Transactions via IDalSession

     [ 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.