Transaction scope not working for Second transaction?
In my application transaction scope is not working for second transaction..It is working fine for first transaction means if an exception is thrown first transactions got rollback but the second one didn't..
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);
}
}
Here cmddb.ExecuteNonQuery()
got rollback but this one
Msg_cust = client.addCustomer(ccode, cname, add1, "", mail)
didn't get rollback Any suggestion?
EDIT:
<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="fals开发者_开发问答e" 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>
What type of web service are you calling, and do you have control over it?
If this is a WCF web service, and you can edit it, then you can use WCF Transaction Flow to control the transaction from the client. Basically your TransactionScope would become a distributed transaction and carried over to the WCF web service. Your transaction would then properly roll back.
More info:
Enabling Transaction Flow (MSDN)
WCF Transaction Propagation (MSDN)
Transaction scope option Required specifies that the database access code would join the existing transaction if one exists. If you would like to commit your second transaction even if the first transaction rolls back, you have to specify RequiresNew.
Web services happen on a different thread (at least) or possibly (even likely) on a different machine. TransactionScope is thread-based. It works based on the current transaction registered against the current thread. Therefore, there's no way to use this facility when making the web service call.
精彩评论