using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
namespace ConsoleApplication4
{
/*代码1:资源管理器*/
public class IEnlistmentNotificationDemo<T, Xcopy> : IEnlistmentNotification
where T : new()
where Xcopy : class
{
T _commitfrontvalue;
T _rollbackfrontvalue = new T();
Xcopy copy;
public IEnlistmentNotificationDemo(T t, Xcopy icopy)
{
//定义一个恢复接口
(icopy as IResourceCopy<T>).Copy(_rollbackfrontvalue, t);
_commitfrontvalue = t;//保持对资源修改的引用
copy = icopy;
}
#region IEnlistmentNotification 成员
public void Prepare(PreparingEnlistment preparingEnlistment)
{
//两阶段提交协议中的准备阶段
Console.WriteLine("准备提交");
string key =
Console.ReadLine();
if (key== "Y" || key == "y")
{
preparingEnlistment.Prepared(); //投票提交事务
}
else if (key == "N" || key == "n")
{
Console.WriteLine("\n由我投票整个事务回滚:" + _rollbackfrontvalue);
(copy as IResourceCopy<T>).Copy(_commitfrontvalue, _rollbackfrontvalue);//回滚事务自愿
preparingEnlistment.ForceRollback();//投票回滚事务,资源管理发生错误时因该将其自动回复数据,
//因为事务管理不会通知发生ForceRollback()方法的管理器。
}
}
public void Commit(Enlistment enlistment)
{
//尝试提交
Console.WriteLine("事务尝试提交");
enlistment.Done();//通知事务管理器,参与者已完成提交工作。
}
public void Rollback(Enlistment enlistment)
{
//事务激活阶段处理错误,执行回滚
Console.WriteLine("操作失败,回滚" + _rollbackfrontvalue);
(copy as IResourceCopy<T>).Copy(_commitfrontvalue, _rollbackfrontvalue);//回滚事务自愿
enlistment.Done();
}
public void InDoubt(Enlistment enlistment)
{
//与其他的资源管理器失去联系
Console.WriteLine("与其他的资源管理器失去联系,通常记录日志");
enlistment.Done();
}
#endregion
}
//代码2:资源复制接口
/// <summary>
/// 事务性资源管理器中的资源拷贝,不同的资源类型存在多种拷贝形式。
/// </summary>
public interface IResourceCopy<T>
{
void Copy(T t1, T t2);
}
//代码3:实现StringBuilder类型的数据复制
/// <summary>
/// StringBuilder类型的数据Copy对象,需要实现IResourceCopy泛型接口。
/// </summary>
public class StringBuilderCopy : IResourceCopy<StringBuilder>
{
#region IResourceCopy<StringBuilder> 成员
public void Copy(StringBuilder oriSb, StringBuilder rollsb)
{
oriSb.Remove(0, oriSb.Length);
oriSb.Append(rollsb.ToString());
}
#endregion
}
//代码4:将自定义的资源管理器参与到事务处理中
/// <summary>
/// 事务范围内的登记资源管理对象的状态
/// </summary>
public class EnlistmentDemo
{
[MethodImpl(MethodImplOptions.Synchronized)]//锁住当前方法,避免多线程访问破坏事务资源的一致性。
public void Start()
{
//易失性资源
StringBuilder stringvalues = new StringBuilder("123");
StringBuilder stringvalues2 = new StringBuilder("456");
StringBuilder stringvalues3 = new StringBuilder("789");
StringBuilder stringvalues4 = new StringBuilder("101112");
//使用资源管理器进行管理
IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy> resource =
new IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy>(stringvalues, new StringBuilderCopy());
IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy> resource2 =
new IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy>(stringvalues2, new StringBuilderCopy());
IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy> resource3 =
new IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy>(stringvalues3, new StringBuilderCopy());
IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy> resource4 =
new IEnlistmentNotificationDemo<StringBuilder, StringBuilderCopy>(stringvalues4, new StringBuilderCopy());
try
{
using (TransactionScope transcope = new TransactionScope())
{
Transaction.Current.TransactionCompleted += new TransactionCompletedEventHandler(commitran_TransactionCompleted);
//登记事务资源管理器,在开始一切事务性操作之前必须先登记资源管理器
Transaction.Current.EnlistVolatile(resource, EnlistmentOptions.None);
Transaction.Current.EnlistVolatile(resource2, EnlistmentOptions.None);
Transaction.Current.EnlistVolatile(resource3, EnlistmentOptions.None);
Transaction.Current.EnlistVolatile(resource4, EnlistmentOptions.None);
//开始事务性操作,该阶段属于事务的激活阶段。
stringvalues.Append("456");
stringvalues2.Append("789");
stringvalues3.Append("101112");
stringvalues4.Append("131415");
transcope.Complete();//开始两阶段提交,该阶段属于事务的准备阶段。
}
}
catch { Console.WriteLine("事务执行出错,执行回滚"); }
//查看被事务性操作后的值
Console.WriteLine("事务完成后的结果值:");
Console.WriteLine(stringvalues + "|" + stringvalues2 + "|" + stringvalues3 + "|" + stringvalues4);
}
//事务结束时触发的事件方法,可以捕获事务执行结果。
void commitran_TransactionCompleted(object sender, TransactionEventArgs e)
{
Console.WriteLine("transaction completed:");
Console.WriteLine("ID: {0}", e.Transaction.TransactionInformation.LocalIdentifier);
Console.WriteLine("Distributed ID: {0}", e.Transaction.TransactionInformation.DistributedIdentifier);
Console.WriteLine("Status: {0}", e.Transaction.TransactionInformation.Status);
Console.WriteLine("IsolationLevel: {0}", e.Transaction.IsolationLevel);
}
}
class Program
{
static void Main(string[] args)
{
EnlistmentDemo svc = new EnlistmentDemo();
svc.Start();
Console.Read();
}
}
}