首先场景是这样的,有两个WebService数据操作,二个本地数据表数据操作!如何能够实现这四个数据操作之间形成一个事务,只要其中一个操作出现问题就中止整个操作,实现操作回滚!也就是说如何实现WebService能够加入到本地数据操作事务中形成一个整体事务! 现在两个WebService都加了这个属性头 [WebMethod(TransactionOption = TransactionOption.RequiresNew)]而本地数据操作用的是    SqlTransaction tran = conn.BeginTransaction()但测试下来本地的两个操作可以回滚,但是WebService不回滚,我查看MSDN只介绍了要在Webservice里面加上TransactionOption = TransactionOption.RequiresNew但具体和本地数据操作一起成为一个事务时没有介绍!~ 
请问有什么方式能解决吗?

解决方案 »

  1.   

    WEB服务中的事务是用WebMethod特性的TransactionOption属性来申明的。如果WEB服务方法执行时发生异常,则自动会终止事务,反之则提交事务。WEB服务的方法仅有两种可能的行为:Disabled,NotSupported,Supported表示不参与事务;Required,RequiresNew表示创建一个新的事务。意思是说当TransactionOption的属性为Required或RequiresNew的WEB服务方法调用另一个TransactionOption的属性为Required或RequiresNew的WEB服务方法时,每个WEB服务方法将参与他们自己的事务。
    PS:WEB服务方法的TransactionOption默认属性为Disabled
    同时我们也可以显示调用System.EnterpriseServices.ContextUtil类的SetAbort方法取消事务,调用SetCompleted方法完成事务。
    例子:
    using System.EnterpriseServices;
    Class WebServiceTransaction:WebService
    {
       pulic void Write(string user,string msg)
       {
         //将接收这两个参数写入数据库
       }
       [WebMethod(TransactionOption=TransactionOption.RequiresNew)]
       public void WiteToDataBasev1(string user,string msg)
       {
          Write(user,msg);
          if(user!="kim")
          {
           string msg="sorry,you can not access";
            throw new UnauthorizedAccessException(msg);
          }
       }   [WebMethod(TransactionOption=TransactionOption.RequiresNew)]
       public void WiteToDataBaseV2(string user,string msg)
       {
          Write(user,msg);
          if(user!="kim")
          {
           ContextUtil.SetAbort();
          }
           else
          {
             ContextUtil.SetComplete();
          }
       }
    }
    测试和预期完全正确。
      

  2.   

    你这是对WebService内部进行异常判断然后是否中止事务,如果在外部调用时如何把WebService里面的事务和外部一起结合成为一个整体事务呢?
    比如有一个A.aspx页面,调用你这个咱们叫A.asmx服务.然后a.aspx里面有两个数据操作
    1. 插入数据
    2. 删除数据
    如何把这两个操作和WebService困绑成一个整体就是所谓的分布式事务,只要其中一个发生异常则中止所有的操作!有例子吗?
      

  3.   

    顶一下,客户端操作如何和WebService成一个整体事务进行操作?
      

  4.   

    SqlConnection conn1st = new SqlConnection("Integrated Security=SSPI;Server=db1;Database=data1");
    conn1st.open();
    SqlCommand sqlCommand = new SqlCommand("UPDATE currentValue SET currentValue=@currentValue", conn1st);
    sqlCommand.Parameters.Add("@currentValue", SqlDbType.Int, 4);
    sqlCommand.Parameters["@currentValue"].Value = newValue;SqlConnection conn2nd = new SqlConnection("Integrated Security=SSPI;Server=db2;Database=data2");
    SqlCommand cmd = new SqlCommand("Insert into tblProduct(UserId,ProductId,CreateDatetime,FromIp) values('Ruren','3c9b8f78-b1c9-47a0-xxxxxx-c6bcca7048b4','2007-12-30 10:56:56','192.168.16.86')",conn2nd);
    conn2nd.open();    --在这行报错
    sqlCommand.ExecuteNonQuery();
    cmd.ExecuteNonQuery();
    分布式事务执行时报"事务已被隐式或显式提交,或已终止。"
      

  5.   

    '3c9b8f78-b1c9-47a0-xxxxxx-c6bcca7048b'  这串打错了,是'3c9b8f78-b1c9-47a0-c6bc-c6bcca7048b'
    SQL语句已经保证是对的。就是在执行两个Connection的时候会出现这种问题~! 提示事务基础管理通讯失败,谁碰以过了?
      

  6.   

     [AutoComplete]
            public void AutoCompletePost(int newValue)
            {
                     SqlConnection dbconn = new SqlConnection("Integrated Security=SSPI;Server=(local);Database=TXDemoDB");
                    SqlCommand sqlCommand = new SqlCommand("UPDATE currentValue SET currentValue='" + newValue + "'", dbconn);
                 
                    dbconn.Open();
                    sqlCommand.ExecuteNonQuery();
                    dbconn.Close();                SqlConnection conn = new SqlConnection("Server=192.168.1.2;Database=Spreader;User Id=sa;pwd=sa");
                    SqlCommand cmd = new SqlCommand("Insert into RightConfig(CName,ID,UserId) values('test',2,'test') ", conn);
                    conn.Open();
                    cmd.ExecuteNonQuery();
                    conn.Close();
     }  参与事务的代码就是这些,两台调用机器的MSDTC的安全配置里面该打钩的都已经打上了. 不知道还有哪里需要设置?另外问一个问题分布式事务难道不能用两个Connection去操作不同的DB吗?? 为什么总是在这里面报错
      

  7.   

    天呀,没人能解决吗???
    ContextUtil.EnableCommit();
                SqlConnection connSp = new SqlConnection("Server=192.168.1.2;Database=db2;Enlist=false;User Id=sa;pwd=sa");            SqlCommand cmd = new SqlCommand("Insert into RightConfig(CName,ID,UserId) values('test',2,'test') ", connSp);            connSp.Open();
                connSp.EnlistDistributedTransaction((ITransaction)ContextUtil.Transaction);
                try
                {                cmd.ExecuteNonQuery();                ContextUtil.SetComplete();
                }
                catch (Exception err)
                {
                    ContextUtil.SetAbort();
                }
                finally {
                    connSp.Close();
                    ContextUtil.DisableCommit();
                }总是报"事务已被隐式或显式提交,或已终止"操作系统是:Windows Server 2003 sp2 数据库是: sql2005
      

  8.   

    上面发错了不好意思,是下面这些代码ContextUtil.EnableCommit();
                SqlConnection connSp = new SqlConnection("Server=192.168.1.2;Database=db2;Enlist=false;User Id=sa;pwd=sa");            SqlCommand cmd = new SqlCommand("Insert into RightConfig(CName,ID,UserId) values('test',2,'test') ", connSp);            connSp.Open();
                connSp.EnlistDistributedTransaction((ITransaction)ContextUtil.Transaction);
                try
                {                cmd.ExecuteNonQuery();                ContextUtil.SetComplete();
                }
                catch (Exception err)
                {
                    ContextUtil.SetAbort();
                }
                finally {
                    connSp.Close();
                    ContextUtil.DisableCommit();
                }总是报"事务已被隐式或显式提交,或已终止"操作系统是:Windows Server 2003 sp2 数据库是: sql2005
      

  9.   

    还是自己解决了,dtcping.exe用的是IP去测试总是通不过.后来改成计算机名就行了.
    需要在hosts里面去加上指定IP的计算机名就ok了~!  散分.谢谢参与者!