You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ibatis.apache.org by "Samuel Clough (JIRA)" <ib...@incubator.apache.org> on 2007/02/27 18:20:05 UTC
[jira] Commented: (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:comment-tabpanel#action_12476233 ]
Samuel Clough commented on IBATISNET-212:
-----------------------------------------
Another possible fix would be to modify the code so that it always nulls the _transaction field and then it could be checked for null. This is another open, although perhaps not as obvious to new users as the OpenTransaction property would be.
> 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
> 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.