4.WCF事务【Transaction】

契约:

namespace Rhythmk.Contracts
{
[ServiceContract(Namespace
="http://wwww.wangkun.com")]

public interface ICalculate
{

[OperationContract]
[TransactionFlow(TransactionFlowOption.Mandatory)]
void OperationTransaction(int i);

/*
TransactionFlow - 指定服务操作是否愿意接受来自客户端的传入事务
NotAllowed - 禁止事务。默认值
Allowed - 允许事务
Mandatory - 强制事务
*/
[OperationContract]
[TransactionFlow(TransactionFlowOption.Mandatory)]
void OperationTransactionExe(int i);

}
}

服务:

using System.ServiceModel;
using Rhythmk.Contracts;

namespace Rhythmk.Services
{
/// <summary>
/// 计算器
/// </summary>
public class Calculate : ICalculate
{
#region ICalculate 成员
/// OperationBehavior - 指定服务方法的本地执行行为
/// 1、TransactionScopeRequired - 如果方法需要事务范围才能执行,则为 true;否则为 false。默认值为 false
/// 将 TransactionScopeRequired 设置为 true,可以要求操作在事务范围内执行。如果流事务可用,则操作会在该事务内执行。如果流事务不可用,则会创建一个新事务并使用它来执行操作
/// 2、TransactionAutoComplete - 默认值为 true
/// true - 当方法完成执行时,将把该事务标志为完成(自动提交事务)
/// false - 需要调用OperationContext.Current.SetTransactionComplete()方法来手工配置该事务的正确完成;否则,该事务将被标志为失败(手动提交事务)
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void OperationTransaction(int i)
{

string sql = "INSERT INTO TB_TEST (name,txt,addtime) VALUES ( 'OperationTransaction','"+(i*i).ToString()+"',GETDATE())";
SqlHelp.ExcuteSqlServer(sql);
}
[OperationBehavior(TransactionScopeRequired
= true, TransactionAutoComplete = true)]
public void OperationTransactionExe(int i)
{

if (i % 10 == 0)
{
throw new Exception("测试事务异常!");
}

string sql = "INSERT INTO TB_TEST (name,txt,addtime) VALUES ( 'OperationTransactionExe','" + (i * i).ToString() + "',GETDATE())";
SqlHelp.ExcuteSqlServer(sql);

}

#endregion
}
}

寄宿

class Program
{
static void Main(string[] args)
{
CreateCalculateService();
}
static void CreateCalculateService()
{
Console.WriteLine(
"----------CreateCalculateService---Star---------");
using (ServiceHost host = new ServiceHost(typeof(Calculate)))
{
host.Opened
+= delegate { Console.WriteLine("CalculateService已经启动,按任意键终止服务!"); };
host.Open();
Console.Read();
}

}
}

服务端配置:

  备注:        <binding name="TransactionConfig" transactionFlow="true"></binding>  需要在配置中开启事务流

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metaBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Rhythmk.Services.Calculate" behaviorConfiguration="metaBehavior" >
<endpoint address=""
binding
="wsHttpBinding" bindingConfiguration="TransactionConfig" contract="Rhythmk.Contracts.ICalculate" >
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:1234/Rhythmk.Services.Calculate"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="TransactionConfig" transactionFlow="true"></binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
</configuration>

通过服务引用调用事务:

public void ExcuteTransaction(int i)
{
RhythmWCF.ICalculate proxy
= new RhythmWCF.CalculateClient();
System.Transactions.TransactionOptions tran
= new System.Transactions.TransactionOptions();
//设置事务超时时间
tran.Timeout = new TimeSpan(3000);
//设置事务的隔离级别
tran.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
using (var ts = new System.Transactions.TransactionScope())
{
try
{
proxy.OperationTransaction(i);
// 输入为10的倍数 将会报告异常 .
proxy.OperationTransactionExe(i);
ts.Complete();
//提交事务
}
catch (Exception ex)
{
lb.Text
= ex.ToString();
}

}
}
一只站在树上的鸟儿,从来不会害怕树枝会断裂,因为它相信的不是树枝,而是它自己的翅膀。与其每天担心未来,不如努力做好现在。
原文地址:https://www.cnblogs.com/rhythmK/p/2066020.html