使用 Monitor 线程插入查询时 SQL 中的死锁 [关闭]

Posted

技术标签:

【中文标题】使用 Monitor 线程插入查询时 SQL 中的死锁 [关闭]【英文标题】:Deadlocks in SQL when using Monitor thread insert query [closed] 【发布时间】:2013-09-17 10:49:48 【问题描述】:

由于某种原因,当我尝试运行 SP 将即时数据插入数据库时​​遇到死锁

使用此表的所有其他线程都工作正常。 当我通过 SQL Server Management Studio 手动向该表添加新行时,它会释放锁并插入队列中的所有值

这是我的代码:

    Queue<IDbCommand> instatntDataCmdQ;

    public void ExecuteInstantDataCmd(int channel, DateTime date, double val, int status)
    
        System.Data.SqlClient.SqlCommand cmd = GetInstantDataCmd( channel, date, val, status);

        lock (instatntDataCmdQ)
        

            try
            
                instatntDataCmdQ.Enqueue(cmd);
                Monitor.Pulse(instatntDataCmdQ);
            
            catch
            
            
        
    



    void thInstantDataRun()
    
        instatntDataCmdQ = new Queue<IDbCommand>(100);
        while (true)
        
            try
            
                IDbCommand cmd;
                lock (instatntDataCmdQ)
                
                    if (instatntDataCmdQ.Count == 0)
                        Monitor.Wait(instatntDataCmdQ);
                    if (instatntDataCmdQ.Count == 0 || (cmd = instatntDataCmdQ.Dequeue()) == null)
                        break;
                
                try
                
                    //open connection.
                    if (cmd.Connection.State == ConnectionState.Closed)
                        cmd.Connection.Open();
                    if (cmd.Connection.State != ConnectionState.Open)
                    
                        cmd.Connection.Close();
                        cmd.Connection.Open();
                    


                    cmd.ExecuteNonQuery();
                
                catch (System.Data.SqlClient.SqlException dex)
                
                        AddDBlog(cmd.Connection, "thInstantDataRun",
                            "Critical error, duplicate dateTime&channel in InstantData table\r\n" + dex.Message);
                
                catch (Exception err)
                
                        AddDBlog(cmd.Connection, "thInstantDataRun", "Error Executing Command " + err.Message);
                
                finally
                
                    //do not close connection
                    //this some time will take up to 1 second and will make the insert of the isntant slow
                    // cmd.Connection.Close();
                    cmd.Dispose();
                    cmd = null; 
                
            
            catch
            
            
        

    

【问题讨论】:

这段代码既复杂又冗长。请简化以获得答案。 嗨,我让它更简单了 最好使用***.com/a/530228/56778 之类的东西来抽象你的队列。不要担心“效率”。数据库更新的成本将淹没几个虚函数调用所花费的微不足道的时间。或者,更好的是,使用 BlockingCollection 之类的东西。 【参考方案1】:

问题是我没有关闭 C# 和 SQL 之间的通信。 状态标志为打开并被卡住。 重新开启通讯后问题解决。

【讨论】:

以上是关于使用 Monitor 线程插入查询时 SQL 中的死锁 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

JAVA多线程之Synchronize 关键字原理

Oracle SQL 中的插入选择查询缺少表达式错误

如何使用 SQL 中的 Case 语句将数据插入临时表

在多线程环境中的 SQL Server 中插入后获取 ID?

如何在sql中插入记录时返回id(id为自动增长)

如何在一个脚本中使用 R 将 SQL 查询中的数据插入到单独的 SQL 查询中?