Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有准备好的语句和事务的SQL Server连接池_C#_.net_Transactions_Sql Server 2012_Prepared Statement - Fatal编程技术网

C# 具有准备好的语句和事务的SQL Server连接池

C# 具有准备好的语句和事务的SQL Server连接池,c#,.net,transactions,sql-server-2012,prepared-statement,C#,.net,Transactions,Sql Server 2012,Prepared Statement,我希望在我的.Net应用程序中利用连接池,但对准备好的语句和事务的支持有些担心。尽管.Net framework似乎提供了为连接池事务提供支持的方法,但我正在尝试确定是否存在对准备语句的类似支持……或者是否需要此类支持。有人知道这个问题的答案吗;DR-.Net SQL Server连接池无缝地处理准备好的语句 我创建了一个主程序来测试这个 private static void TestPreparedStatement() { const string sql = "INSERT IN

我希望在我的.Net应用程序中利用连接池,但对准备好的语句和事务的支持有些担心。尽管.Net framework似乎提供了为连接池事务提供支持的方法,但我正在尝试确定是否存在对准备语句的类似支持……或者是否需要此类支持。有人知道这个问题的答案吗;DR-.Net SQL Server连接池无缝地处理准备好的语句

我创建了一个主程序来测试这个

private static void TestPreparedStatement()
{
    const string sql = "INSERT INTO myTable(id, numInt) " +
                       "VALUES((SELECT MAX(id) " +
                               "FROM myTable) + 1, @numInt);";
    using (SqlConnection dbConn = new SqlConnection(s_connStr))
    {
        dbConn.Open();
        Console.WriteLine("Getting ready to prepare statement on connection with ID " + dbConn.ClientConnectionId);
        s_cmd = new SqlCommand(sql, dbConn);
        s_cmd.Parameters.Add("@numInt", SqlDbType.Int);
        s_cmd.Prepare();
        Console.WriteLine("The command has been prepared.");
    }

    for (int threadNdx = 0; threadNdx < 10; ++threadNdx)
    {
        Thread prepStmntThread = new Thread(ExecPrepStmnt)
        {
            Name = threadNdx.ToString()
        };

        prepStmntThread.Start();
    }
}

private static void ExecPrepStmnt()
{
    using (SqlConnection dbConn = new SqlConnection(s_connStr))
    {
        dbConn.Open();
        lock (s_cmd)
        {
            Console.WriteLine("Thread #" + Thread.CurrentThread.Name + " has ownership of the command.");
            s_cmd.Connection = dbConn;
            s_cmd.Parameters["@numInt"].Value = int.Parse(Thread.CurrentThread.Name);
            Console.WriteLine("Thread #" + Thread.CurrentThread.Name + " is about to execute the command on the connection with ID " + s_cmd.Connection.ClientConnectionId + ".");
            try
            {
                s_cmd.ExecuteNonQuery();
                Console.WriteLine("Thread #" + Thread.CurrentThread.Name + " successfully executed the command.");
            }
            catch (Exception e)
            {
                Console.WriteLine("Thread #" + Thread.CurrentThread.Name + " failed to execute the command.");
                Console.WriteLine(e.Message);
            }

            Console.WriteLine("Thread #" + Thread.CurrentThread.Name + " is about to relinquish ownership of the command.");
        }

        Console.WriteLine("Thread #" + Thread.CurrentThread.Name + " is going to sleep with open pooled connection.");
        Thread.Sleep(5 * 1000);
    }

    Console.WriteLine("Thread #" + Thread.CurrentThread.Name + " has woken up and disposed of its pooled connection.");
}
所以基本上看起来没什么好担心的。当我运行上面的测试程序时,我的老板在数据库服务器上运行了一个SQL Server配置文件,并声称他从来没有看到过对sp_prepare的调用。考虑到SQL Server缓存执行计划的事实,这可能不是什么大问题


不幸的是,自从写了我的问题之后,我意识到SqlConnection.EnstractTransaction方法在我的特定环境中并不像我最初希望的那样有用。由于这一事实,在我的应用程序中,我们似乎必须将交易作为一种特殊情况来处理。

推荐的、时髦的处理交易的新方法不是显式地处理它们,而是使用TransactionScope。TransactionScope中的任何内容都将被登记,省去了显式地将它们分配给连接和命令以及在较低级别了解它们的麻烦。同时,连接池通常是您最不需要担心的事情-当涉及到从池中获取现有连接或创建新连接时,SqlConnection只会做正确的事情。对……不幸的是,这对我不起作用。这是一个web应用程序,有人会提出启动事务的请求,然后是在该事务上下文中执行语句的多个中间请求,最后是提交或回滚事务的请求。因此,在单个请求执行的范围内绑定它是不可行的…当然,除非我遗漏了什么。好吧,可以使用有状态WCF服务并将事务绑定到该服务上。。。但这是非常不推荐的,因为在锁的持续时间内,您将受到客户端的摆布。根据定义,任何将事务与远程客户端混合的设计都是糟糕的。。。但这超出了这个问题的范围。
Getting ready to prepare statement on connection with ID 289ae798-7564-4b7c-b45f-60d09d54fa87
The command has been prepared.
Thread #0 has ownership of the command.
Thread #0 is about to execute the command on the connection with ID 289ae798-7564-4b7c-b45f-60d09d54fa87.
Thread #0 successfully executed the command.
Thread #0 is about to relinquish ownership of the command.
Thread #0 is going to sleep with open pooled connection.
Thread #2 has ownership of the command.
Thread #2 is about to execute the command on the connection with ID 2585e1fb-980a-45ee-9a59-17d94f44b2d5.
Thread #2 successfully executed the command.
Thread #2 is about to relinquish ownership of the command.
Thread #2 is going to sleep with open pooled connection.
Thread #1 has ownership of the command.
Thread #1 is about to execute the command on the connection with ID 2772d6a2-dc23-472d-bb4e-adfa99e97bdf.
Thread #1 successfully executed the command.
Thread #1 is about to relinquish ownership of the command.
Thread #1 is going to sleep with open pooled connection.
Thread #3 has ownership of the command.
Thread #3 is about to execute the command on the connection with ID 1ce7f447-f485-4b85-9ede-2854fc160a83.
Thread #3 successfully executed the command.
Thread #3 is about to relinquish ownership of the command.
Thread #3 is going to sleep with open pooled connection.
Thread #4 has ownership of the command.
Thread #4 is about to execute the command on the connection with ID 62d62a9c-b2e0-42e5-99da-3682cf7614ee.
Thread #4 successfully executed the command.
Thread #4 is about to relinquish ownership of the command.
Thread #4 is going to sleep with open pooled connection.
Thread #5 has ownership of the command.
Thread #5 is about to execute the command on the connection with ID cb62e434-534a-49a7-afbd-96e85f7e5888.
Thread #5 successfully executed the command.
Thread #5 is about to relinquish ownership of the command.
Thread #5 is going to sleep with open pooled connection.
Thread #6 has ownership of the command.
Thread #6 is about to execute the command on the connection with ID 946ccf21-a278-46ad-871f-5030ee00fcd0.
Thread #6 successfully executed the command.
Thread #6 is about to relinquish ownership of the command.
Thread #6 is going to sleep with open pooled connection.
Thread #7 has ownership of the command.
Thread #7 is about to execute the command on the connection with ID a4b36316-8f82-44ff-998b-f33b94b34320.
Thread #7 successfully executed the command.
Thread #7 is about to relinquish ownership of the command.
Thread #7 is going to sleep with open pooled connection.
Thread #8 has ownership of the command.
Thread #8 is about to execute the command on the connection with ID 11f558a0-128d-4401-94cb-57fff007ae81.
Thread #8 successfully executed the command.
Thread #8 is about to relinquish ownership of the command.
Thread #8 is going to sleep with open pooled connection.
Thread #9 has ownership of the command.
Thread #9 is about to execute the command on the connection with ID c613e347-1471-4476-a6d7-1485e2c731c5.
Thread #9 successfully executed the command.
Thread #9 is about to relinquish ownership of the command.
Thread #9 is going to sleep with open pooled connection.
Thread #0 has woken up and disposed of its pooled connection.
Thread #2 has woken up and disposed of its pooled connection.
Thread #1 has woken up and disposed of its pooled connection.
Thread #3 has woken up and disposed of its pooled connection.
Thread #4 has woken up and disposed of its pooled connection.
Thread #5 has woken up and disposed of its pooled connection.
Thread #6 has woken up and disposed of its pooled connection.
Thread #7 has woken up and disposed of its pooled connection.
Thread #8 has woken up and disposed of its pooled connection.
Thread #9 has woken up and disposed of its pooled connection.