I am playing a few days with annoying problem with stored procedure with linked server usage. On the server I have shared DB. The server is running MS SQL Server 2008 EE sp3. As new user I cannot put images so I will try without
So assume that I have stored procedure which looks
CREATE PROCEDURE [dbo].[spSynchronizeArticles]
-- Add the parameters for the stored procedure here
(
@pDebug bit,
@siteId bigint
)
AS
BEGIN
SELECT *
FROM [LinkedServer].[MyDatabase].dbo.Storages
WHERE Storage.siteId = @siteId
RETURN 0
END
Where linked server is configured
EDIT:
enable promotion of distributed transaction = false
RPC = false
RPC out = false
When I run query from MS SQL Management studio it always runs successfully. When I run query from c# application code
StringBuilder sb;
public bool ActualizeArticlesFromServer(Int64 siteId, out string messages)
{
SqlCommand sqlCmd = new SqlCommand("spSynchronizeArticles");
try
{
sb = new StringBuilder();
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue("@pDebug", "false");
sqlCmd.Parameters.AddWithValue("@siteId", siteId);
// Return value as parameter
SqlParameter returnValue = new SqlParameter("returnVal", SqlDbType.Int);
returnValue.Direction = ParameterDirection.ReturnValue;
sqlCmd.Parameters.Add(returnValue);
using (SqlConnection conn = new SqlConnection(Context.LocalData.ConnectionString))
{
try
{
try
{
conn.Open();
sqlCmd.Connection = conn;
//TODO: find out how to print from stored procedure
//((SqlConnection)Context.LocalData.Connection).InfoMessage += new SqlInfoMessageEventHandler(Connection_InfoMessage);
sqlCmd.ExecuteScalar();
}
catch (Exception ex)
{
Log.LogMethodException(ex);
return false;
}
}
finally
{
try
{
conn.Close();
}
catch (Exception ex)
{
Log.LogMethodException(ex);
}
}
}
return Convert.ToInt64(returnValue.Value) == 0;
}
finally
{
messages = sb.ToString();
}
}
I have in the application the list of users, but it is internally solved. No windows users.
When I run this code for actual user, everything is OK, I can run query more time. Then I change the user and try to execute the Procedure from above code I got the exception
System.Data.SqlClient.SqlException (0x80131904): The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "someServer" was unable to begin a distributed transaction.
When I restart whole application the query again works OK. I do not know if it has something with connection pooling or what?
I think that distributed transaction somehow hangs up (but in SQL no transaction used).
In the DTC statistics I can see the active transaction even when exception is fired.
I have set the DTC component on both client and server do allow everything (it is in Czech language, but I hope it is clear enough)
Network DTC Access checked
Allow inbound true
Allow outbound true
No authentication Required
The server SQL server is installed on virtual computer with Microsoft Windows Server 2008. when the DTC is set on Windows server and also on virtual windows server. The firewall was turn out for testing on server and also on virtual.
EDIT2:
OK. So I made some research and looks that @JanVanHerck was right. It is still confusing for me, but I will try to write what I did.
- I turn off the MS DTC
- First time when I run my application code to execute stored procedure and works fine
- Then I logged out and my logout method did something which I explain bellow.
- I login with same user name (does not matter indeed) and run my application code to execute stored procedure and the exception that MS DTC is not running on computer rises.
Note: There is no transaction (neither distributed transaction) inside the stored procedure.
So I check the logout method and I find out that I am updating one local table within transaction - I commented the transaction in code and everything is working.
I will try to put it in productive system and will see, but we have some improving here. Thanks @JanVanHerck. Actually I did not check my code before, because I did not know that it could have impact on executing procedure.
But interesting is that MS DTC goes into to sight after the transaction was used (even only in local DB).