C# 从.NET应用程序中,内部带有链接服务器选择查询的简单存储过程只工作一次
我玩了几天与链接服务器使用的存储过程恼人的问题。在服务器上,我共享了数据库。服务器正在运行MS SQL server 2008 EE sp3。作为新用户,我无法放置图像,因此我将尝试不放置图像 假设我有一个存储过程C# 从.NET应用程序中,内部带有链接服务器选择查询的简单存储过程只工作一次,c#,.net,linked-server,sql-server-2008-express,C#,.net,Linked Server,Sql Server 2008 Express,我玩了几天与链接服务器使用的存储过程恼人的问题。在服务器上,我共享了数据库。服务器正在运行MS SQL server 2008 EE sp3。作为新用户,我无法放置图像,因此我将尝试不放置图像 假设我有一个存储过程 CREATE PROCEDURE [dbo].[spSynchronizeArticles] -- Add the parameters for the stored procedure here ( @pDebug bit, @siteId bigint
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
配置链接服务器的位置
编辑:
当我从MS SQL Management studio运行查询时,它总是成功运行。当我从c应用程序代码运行查询时
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();
}
}
我在应用程序中有用户列表,但它是内部解决的。没有windows用户
当我为实际用户运行此代码时,一切正常,我可以运行查询更多时间。然后我更改了用户,并尝试从上面的代码执行过程,我得到了异常
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.
当我重新启动整个应用程序时,查询再次正常工作。我不知道它是否与连接池或什么有关
我认为分布式事务以某种方式挂起,但在SQL中没有使用任何事务
在DTC统计信息中,我可以看到激活的事务,即使触发了异常
我已经在客户机和服务器上设置了DTC组件,但我希望它足够清晰
Network DTC Access checked
Allow inbound true
Allow outbound true
No authentication Required
SQL server服务器安装在带有Microsoft Windows server 2008的虚拟计算机上。在Windows server和虚拟Windows server上设置DTC时。防火墙是为了在服务器和虚拟机上进行测试而推出的
编辑2:
嗯。所以我做了一些研究,看起来@JanVanHerck是对的。这对我来说仍然很困惑,但我会尝试写下我所做的
我关闭MS DTC
第一次运行我的应用程序代码来执行存储过程并运行良好时
然后我注销了,我的注销方法做了一些事情,我解释如下。
我用相同的用户名登录并不重要,我运行我的应用程序代码来执行存储过程,但计算机上没有运行MS DTC的情况除外。
注意:存储过程中没有事务,也没有分布式事务
所以我检查了注销方法,发现我正在更新事务中的一个本地表——我用代码注释了事务,一切都正常
我会尝试把它放在生产系统中,并会看到,但我们在这里有一些改进。谢谢@JanVanHerck。实际上,我以前并没有检查我的代码,因为我不知道它会对执行过程产生影响
但有趣的是,即使仅在本地数据库中使用事务后,MS DTC也会出现 在我看来,不应该在您提供的代码中寻找错误,而应该在用户切换方法中寻找错误,留下一些混乱。@JanVanHerck:我会检查一下,但是应用程序已经运行了几年,所有SQL操作都没有问题,除了这个。我正在调用更多的存储过程,这些存储过程只能从代码中使用本地数据库。在这种情况下,我一直使用SQLConnection作为新对象,但我认为有一些.NET正在管理的池,我不知道会有什么问题以及如何找到它。
Network DTC Access checked
Allow inbound true
Allow outbound true
No authentication Required