none
|zyciis| WCF服务事务操作,我自己写的一个例子,大家看有没有问题,谢谢 RRS feed

  • 问题

  • 示例下载地址
    http://www.innoworkspc.com/error/wcftest.rar


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using System.Data.SqlClient;
    using System.Data;

    namespace WCFService
    {
        // 注意: 如果更改此处的类名 "Test",也必须更新 Web.config 中对 "Test" 的引用。
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
        [ServiceContract(SessionMode = SessionMode.Required)]
        public class Test
        {
            SqlConnection con;
            SqlCommand cmd;
            SqlTransaction tran;
            /// <summary>
            /// 创建链接
            /// </summary>
            [OperationContract]
            [FaultContract(typeof(OverflowException))]
            public void CreateCon()
            {
                con = new SqlConnection("Data Source=.;user id=sa;database=Test");
                con.Open();
                tran = con.BeginTransaction();
            }

            /// <summary>
            /// 出错处理,回滚理务
            /// </summary>
            public void ErrorCon(Exception ex)
            {
                if (tran != null)
                {
                    tran.Rollback();
                    tran.Dispose();
                    tran = null;
                }
                CloseCon();
                throw ex;
            }

            /// <summary>
            /// 关才处理,如果有事务就提交事务
            /// </summary>
            [OperationContract]
            [FaultContract(typeof(OverflowException))]
            public void CloseCon()
            {
                if (tran != null)
                {
                    tran.Commit();
                }
                con.Close();
                con.Dispose();
            }

            [OperationContract]
            [FaultContract(typeof(OverflowException))]
            public void Insert(string name, string pass)
            {
                try
                {
                    if (name == pass)
                    {
                        throw new Exception("name和pass不能相同");
                    }
                    string cmdText = "Insert Into MyUser(Name,Pass) values (@Name,@Pass)";
                    cmd = new SqlCommand();
                    cmd.CommandText = cmdText;
                    cmd.Connection = con;
                    cmd.Transaction = tran;
                    cmd.Parameters.Add(new SqlParameter("@Name", name));
                    cmd.Parameters.Add(new SqlParameter("@Pass", pass));
                    cmd.ExecuteNonQuery();

                }
                catch (Exception ex)
                {
                    ErrorCon(ex);
                }
            }


        }
    }

    -----------------------------------------------------------------------------

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace WCFClient
    {
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {

            }

            protected void btnInsert_Click(object sender, EventArgs e)
            {
                //创建一个WCF对像
                Test.TestClient client = new WCFClient.Test.TestClient();
                //在WCF服务中建立一个数据库链接和启动事务
                client.CreateCon();
                //插入一条记录
                client.Insert("AAA", "123456");
                //插入一条记录
                client.Insert("BBB", "654321");
                //提交事务并关闭数据库链接
                client.CloseCon();
                //关闭WCF服务
                client.Close();
            }

            protected void btnInsertError_Click(object sender, EventArgs e)
            {
                //创建一个WCF对像
                Test.TestClient client = new WCFClient.Test.TestClient();
                //在WCF服务中建立一个数据库链接和启动事务
                client.CreateCon();
                //插入一条记录
                client.Insert("CCC", "123456");
                //插入一条记录 //这里会出错,WCF中加滚事务
                client.Insert("DDD", "DDD");
                //提交事务并关闭数据库链接
                client.CloseCon();
                //关闭WCF服务
                client.Close();
            }
        }
    }


    请问,我这样做的示例思想行不行,不然要怎么做,谢谢

    2009年10月30日 4:32

答案

  • Hi,
    这里看不出你启用事务的设置啊。
      这样综合作用,匹配的结果就是3种启动事务的模式。分别是:Client/Service transaction、Client transaction、Service transaction模式。他们分别的设置情况是:

    【5.1】. Client/Service transaction,最常见的一种事务模型,通常由客户端或服务本身启用一个事务。设置步骤:
    (1) 选择一个支持事务的Binding,设置 TransactionFlow = true。
    (2) 设置 TransactionFlow(TransactionFlowOption.Allowed)。
    (3) 设置 OperationBehavior(TransactionScopeRequired=true)。
    【5.2】. Client transaction,强制服务必须参与事务,而且必须是客户端启用事务。设置步骤:
    (1) 选择一个支持事务的Binding,设置 TransactionFlow = true。
    (2) 设置 TransactionFlow(TransactionFlowOption.Mandatory)。
    (3) 设置 OperationBehavior(TransactionScopeRequired=true)。
    【5.3】. Service transaction,服务必须启用一个根事务,且不参与任何外部事务。设置步骤:
    (1) 选择任何一种Binding,设置 TransactionFlow = false(默认)。
    (2) 设置 TransactionFlow(TransactionFlowOption.NotAllowed)。
    (3) 设置 OperationBehavior(TransactionScopeRequired=true)。
    WCF的三种事务模式,你使用的是哪一种?
    这个 //需要事务环境,启动事务        [OperationBehavior(TransactionScopeRequired = true)]//你也没有使用啊。

    你可以参考一下
    WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程


    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
    欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
    欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
    欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF Forum
    2009年10月30日 10:22
    版主