You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
|
|
|
|
namespace Connected.ServiceModel.Transactions
|
|
|
|
|
{
|
|
|
|
|
internal class TransactionContext : ITransactionContext
|
|
|
|
|
{
|
|
|
|
|
private ConcurrentStack<ITransactionClient> _operations;
|
|
|
|
|
private MiddlewareTransactionState _state = MiddlewareTransactionState.Active;
|
|
|
|
|
|
|
|
|
|
public event EventHandler? StateChanged;
|
|
|
|
|
|
|
|
|
|
public MiddlewareTransactionState State
|
|
|
|
|
{
|
|
|
|
|
get => _state; private set
|
|
|
|
|
{
|
|
|
|
|
if (_state != value)
|
|
|
|
|
{
|
|
|
|
|
_state = value;
|
|
|
|
|
StateChanged?.Invoke(this, EventArgs.Empty);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ConcurrentStack<ITransactionClient> Operations => _operations ??= new ConcurrentStack<ITransactionClient>();
|
|
|
|
|
|
|
|
|
|
public bool IsDirty { get; set; }
|
|
|
|
|
|
|
|
|
|
public void Register(ITransactionClient client)
|
|
|
|
|
{
|
|
|
|
|
if (client is null || Operations.Contains(client))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Operations.Push(client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task Commit()
|
|
|
|
|
{
|
|
|
|
|
State = MiddlewareTransactionState.Committing;
|
|
|
|
|
|
|
|
|
|
while (!Operations.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
if (Operations.TryPop(out ITransactionClient? op))
|
|
|
|
|
await op?.Commit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
State = MiddlewareTransactionState.Completed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task Rollback()
|
|
|
|
|
{
|
|
|
|
|
State = MiddlewareTransactionState.Reverting;
|
|
|
|
|
|
|
|
|
|
while (!Operations.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
if (Operations.TryPop(out ITransactionClient? op))
|
|
|
|
|
await op?.Rollback();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
State = MiddlewareTransactionState.Completed;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|