在我的应用程序中,事务范围不适用于第二个事务。它对第一个事务工作正常意味着如果抛出异常,则第一个事务得到回滚,但第二个事务没有...
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>
答案 0 :(得分:2)
您打电话给哪种类型的网络服务,您是否可以控制它?
如果这是WCF Web服务,并且您可以对其进行编辑,则可以使用 WCF事务流来控制来自客户端的事务。基本上,您的TransactionScope将成为分布式事务并转移到WCF Web服务。然后,您的交易将正确回滚。
更多信息:
答案 1 :(得分:0)
事务范围选项Required指定数据库访问代码将加入现有事务(如果存在)。如果您想提交第二个事务,即使第一个事务回滚,您也必须指定RequiresNew。
答案 2 :(得分:0)
Web服务发生在不同的线程上(至少)或可能(甚至可能)在不同的机器上。 TransactionScope是基于线程的。它基于当前线程注册的当前事务工作。因此,在进行Web服务调用时无法使用此工具。