交易范围不适用于第二笔交易?

时间:2011-06-29 14:52:22

标签: c# database web-services transactionscope

在我的应用程序中,事务范围不适用于第二个事务。它对第一个事务工作正常意味着如果抛出异常,则第一个事务得到回滚,但第二个事务没有...

public string InsertRealm(string adminuser, string adminpassword, string CustomerCode, string CustomerName, string address, string email, string phone, string NoOfUsers, string ProductType)
{

  try 
  {
    using (Transactions.TransactionScope scope = new Transactions.TransactionScope(TransactionScopeOption.Required, new TimeSpan(2, 0, 0))) {
      string _strServer = sqlmethod.Read_config("deploymentSetting", "Server");
      string _strDatabase = sqlmethod.Read_config("deploymentSetting", "database");
      string _strUserid = sqlmethod.Read_config("deploymentSetting", "username");
      string _strPassword = sqlmethod.Read_config("deploymentSetting", "password");
      string constr_str = "server=" + _strServer + ";" + "database=" + _strDatabase + ";" + "uid=" + _strUserid + ";" + "pwd=" + _strPassword + ";";

      string _blankdbCrm = sqlmethod.Read_config("dbSettings", "blankcrmdbName");
      string userCountdb = sqlmethod.Read_config("dbSettings", "userCountdb");
      string bakRestorePath = sqlmethod.Read_config("dbSettings", "bakRestorePath");
      string mdfRestorePath = sqlmethod.Read_config("dbSettings", "mdfRestorePath");
      string ldfRestorePath = sqlmethod.Read_config("dbSettings", "ldfRestorePath");
      string _dbCrm = "";

      con.ConnectionString = constr_str;


      if (flag == "Yes") 
      {
        SqlCommand cmddb = new SqlCommand("crt_crm_db_details", con);
        cmddb.CommandType = CommandType.StoredProcedure;
        cmddb.CommandTimeout = 0;
        cmddb.Parameters.Add("@custname", SqlDbType.NVarChar).Value = ccode;
        cmddb.Parameters.Add("@blank_dbname", SqlDbType.NVarChar).Value = _blankdbCrm;
        cmddb.Parameters.Add("@blank_bakpath", SqlDbType.NVarChar).Value = bakRestorePath;
        cmddb.Parameters.Add("@blank_mdfpath", SqlDbType.NVarChar).Value = mdfRestorePath;
        cmddb.Parameters.Add("@blank_ldfpath", SqlDbType.NVarChar).Value = ldfRestorePath;
        cmddb.Parameters.Add("@usercnt", SqlDbType.NVarChar).Value = userCountdb;

        SqlParameter Typedb = new SqlParameter("@errorid", SqlDbType.NVarChar);
        Typedb.Direction = ParameterDirection.Output;
        Typedb.Value = null;
        Typedb.Size = 50;
        cmddb.Parameters.Add(Typedb);
        try 
        {
          con.Open();
          cmddb.ExecuteNonQuery();
        }
        catch (SqlException ee) 
        {
          VWLogger.LogMessage("Exception in crt_crm_db_details:", TraceEventType.Critical);
          VWLogger.LogMessage(ee, TraceEventType.Critical);
          return ee.Message;
          flag = ee.Errors(0).ToString();
        }
        con.Close();
      }

      if (flag == "Yes") 
      {
        Ramco.VW.Types.Message[] Msg_cust = null;
        try 
        {
          Msg_cust = client.addCustomer(ccode, cname, add1, "", mail);
        } 
        catch (SqlException ex)
        {
          VWLogger.LogMessage("Exception in addCustomer:", TraceEventType.Critical);
          VWLogger.LogMessage(ex, TraceEventType.Critical);
          return ex.Message;
          flag = ex.Errors(0).ToString();
        }
      }

      scope.Complete();
      return "Success";
    }

  } 
  catch (Exception ex) 
  {
    VWLogger.LogMessage("Exception in insertrealm:", TraceEventType.Critical);
    VWLogger.LogMessage(ex, TraceEventType.Critical);
    return ex.Message;
    throw new  CustomSoapException(CustomSoapException.ExceptionCode.AuthenticationException, ex.Message);
  }

}

这里cmddb.ExecuteNonQuery()得到回滚但是这个

Msg_cust = client.addCustomer(ccode, cname, add1, "", mail)

没有回滚任何建议?

编辑:

<bindings>
      <basicHttpBinding>
        <binding name="UserNameTokenOverSSLBinding">
          <security mode="TransportWithMessageCredential" />
        </binding>
        <binding name="BinaryCertTokenOverSSLBinding" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
         <binding name="Vw30BasicHttpBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferSize="65536" maxReceivedMessageSize="65536">
          <security>
            <transport clientCredentialType="None" />
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </basicHttpBinding>
      <customBinding>
          <binding name="Vw30netTcpHABinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00">
            <binaryMessageEncoding>
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
            </binaryMessageEncoding>
            <tcpTransport maxBufferPoolSize="524288" maxReceivedMessageSize="99999998" connectionBufferSize="8192" hostNameComparisonMode="StrongWildcard" channelInitializationTimeout="00:01:00" maxBufferSize="99999998" maxPendingConnections="20" maxOutputDelay="00:00:00.2000000" maxPendingAccepts="5" transferMode="Buffered" listenBacklog="20" portSharingEnabled="false" teredoEnabled="false">
            <connectionPoolSettings groupName="default" leaseTimeout="00:00:02" idleTimeout="00:02:00" maxOutboundConnectionsPerEndpoint="20" />
            </tcpTransport>
            </binding>
            <binding name="Vw30HttpHABinding">
            <textMessageEncoding />
            <httpTransport keepAliveEnabled="false">
            </httpTransport>
        </binding> 

        <binding name="UserNameTokenOverSSLOffloaderBinding">
          <textMessageEncoding messageVersion="Soap11" />
          <security authenticationMode="UserNameOverTransport">
            <secureConversationBootstrap />
          </security>
          <sslOffloadedHttpsTransport />
        </binding>
        <binding name="BinaryCertTokenOverSSLOffloaderBinding">
          <textMessageEncoding messageVersion="Soap11" />
          <security authenticationMode="UserNameOverTransport">
            <secureConversationBootstrap />
          </security>
          <sslOffloadedHttpsTransport />
        </binding>
      </customBinding>
      <netTcpBinding>
        <binding name="Vw30netTcpBinding" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:05:00" sendTimeout="00:05:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
          <security mode="None">
            <transport clientCredentialType="None" protectionLevel="None" />
            <message clientCredentialType="None" />
          </security>
        </binding>
      </netTcpBinding>
      <wsHttpBinding>
        <binding name="WSUserNameBinding" transactionFlow="true">
          <security>
            <transport clientCredentialType="None" />
            <message clientCredentialType="UserName" negotiateServiceCredential="false" establishSecurityContext="false" />
          </security>
        </binding>
        <binding name="WSBinaryCertBinding" transactionFlow="true">
          <security>
            <transport clientCredentialType="None" />
            <message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false" />
          </security>
        </binding>
        <binding name="WSUserNameReliableBinding" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="true">
          <reliableSession enabled="true" />
          <security>
            <transport clientCredentialType="None" />
            <message clientCredentialType="UserName" negotiateServiceCredential="false" />
          </security>
        </binding>
        <binding name="WsBinaryCertReliableBinding" transactionFlow="true">
          <reliableSession enabled="true" />
          <security>
            <transport clientCredentialType="None" />
            <message clientCredentialType="Certificate" negotiateServiceCredential="false" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

3 个答案:

答案 0 :(得分:2)

您打电话给哪种类型的网络服务,您是否可以控制它?

如果这是WCF Web服务,并且您可以对其进行编辑,则可以使用 WCF事务流来控制来自客户端的事务。基本上,您的TransactionScope将成为分布式事务并转移到WCF Web服务。然后,您的交易将正确回滚。

更多信息:

Enabling Transaction Flow (MSDN)

WCF Transaction Propagation (MSDN)

答案 1 :(得分:0)

事务范围选项Required指定数据库访问代码将加入现有事务(如果存在)。如果您想提交第二个事务,即使第一个事务回滚,您也必须指定RequiresNew。

答案 2 :(得分:0)

Web服务发生在不同的线程上(至少)或可能(甚至可能)在不同的机器上。 TransactionScope是基于线程的。它基于当前线程注册的当前事务工作。因此,在进行Web服务调用时无法使用此工具。