blob: 574d3162ac4e82abc5d6d369da2e469684ff3496 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Apache.NMS.Stomp.Commands;
using System.Collections;
namespace Apache.NMS.Stomp
{
public enum TransactionType
{
Begin = 0, Commit = 1, Rollback = 2
}
}
namespace Apache.NMS.Stomp
{
public class TransactionContext
{
private TransactionId transactionId;
private readonly Session session;
private readonly ArrayList synchronizations = ArrayList.Synchronized(new ArrayList());
public TransactionContext(Session session)
{
this.session = session;
}
public bool InTransaction
{
get{ return this.transactionId != null; }
}
public TransactionId TransactionId
{
get { return transactionId; }
}
/// <summary>
/// Method AddSynchronization
/// </summary>
public void AddSynchronization(ISynchronization synchronization)
{
synchronizations.Add(synchronization);
}
public void RemoveSynchronization(ISynchronization synchronization)
{
synchronizations.Remove(synchronization);
}
public void ResetTransactionInProgress()
{
if(InTransaction)
{
this.transactionId = null;
this.synchronizations.Clear();
}
}
#region Transaction State Events
public event SessionTxEventDelegate TransactionStartedListener;
public event SessionTxEventDelegate TransactionCommittedListener;
public event SessionTxEventDelegate TransactionRolledBackListener;
#endregion
public void Begin()
{
if(!InTransaction)
{
this.transactionId = this.session.Connection.CreateLocalTransactionId();
TransactionInfo info = new TransactionInfo();
info.ConnectionId = this.session.Connection.ConnectionId;
info.TransactionId = transactionId;
info.Type = (int) TransactionType.Begin;
this.session.Connection.Oneway(info);
if(this.TransactionStartedListener != null)
{
this.TransactionStartedListener(this.session);
}
}
}
public void Rollback()
{
if(!InTransaction)
{
throw new NMSException("Invliad State: Not Currently in a Transaction");
}
this.BeforeEnd();
TransactionInfo info = new TransactionInfo();
info.ConnectionId = this.session.Connection.ConnectionId;
info.TransactionId = transactionId;
info.Type = (int) TransactionType.Rollback;
this.transactionId = null;
this.session.Connection.SyncRequest(info);
this.AfterRollback();
this.synchronizations.Clear();
}
public void Commit()
{
if(!InTransaction)
{
throw new NMSException("Invliad State: Not Currently in a Transaction");
}
this.BeforeEnd();
TransactionInfo info = new TransactionInfo();
info.ConnectionId = this.session.Connection.ConnectionId;
info.TransactionId = transactionId;
info.Type = (int) TransactionType.Commit;
this.transactionId = null;
this.session.Connection.SyncRequest(info);
this.AfterCommit();
this.synchronizations.Clear();
}
internal void BeforeEnd()
{
lock(this.synchronizations.SyncRoot)
{
foreach(ISynchronization synchronization in this.synchronizations)
{
synchronization.BeforeEnd();
}
}
}
internal void AfterCommit()
{
lock(this.synchronizations.SyncRoot)
{
foreach(ISynchronization synchronization in this.synchronizations)
{
synchronization.AfterCommit();
}
if(this.TransactionCommittedListener != null)
{
this.TransactionCommittedListener(this.session);
}
}
}
internal void AfterRollback()
{
lock(this.synchronizations.SyncRoot)
{
foreach(ISynchronization synchronization in this.synchronizations)
{
synchronization.AfterRollback();
}
if(this.TransactionRolledBackListener != null)
{
this.TransactionRolledBackListener(this.session);
}
}
}
}
}