一个线程
lock(A){sleep(1000);lock(B){
.....
.....
}
}一个线程
lock(B){
sleep(500);
lock(A){
.....
.....
}
}两个线程启动最终死锁谁也无法继续运行具体去看书吧有个四条件

解决方案 »

  1.   

    不应该啊,单纯的多线程insert不可能造成表锁的。
    你关键部分的入库操作的代码没有啊,严重怀疑是反复开关数据库连接造成的数据连接池响应不能,导致失败。
      

  2.   


    public static int SaveOnceData(DateTime tagdt, string tagcd, string tagvl)
            {
                try
                {
                    if (mc.State != System.Data.ConnectionState.Open)
                        mc.Open();                int rtn = 0;                string sqlCmd = "insert DELAYED into tagonce(tagdatetime, tagcode, tagval) values(?tagdatetime, ?tagcode, ?tagval)";                if (mc != null)
                    {
                        MySqlCommand cmd = new MySqlCommand(sqlCmd, mc);
                        cmd.CommandTimeout = 5;                    cmd.Parameters.Add("?tagdatetime", MySqlDbType.Timestamp);
                        cmd.Parameters["?tagdatetime"].Value = tagdt;                    cmd.Parameters.Add("?tagcode", MySqlDbType.Text);
                        cmd.Parameters["?tagcode"].Value = tagcd;                    cmd.Parameters.Add("?tagval", MySqlDbType.Text);
                        cmd.Parameters["?tagval"].Value = tagvl;                    rtn = cmd.ExecuteNonQuery();
                    }                return rtn;
                }
                catch (Exception e)
                {
                    return 0;
                }
            }
      

  3.   

    综上所述,用lock 控制多线程操作 队列,然后单独开一个线程写数据库操作 
      

  4.   

    很明显,发数过大了,导致数据库连接数量不足,要解决问题,
    1,加大MySql的并发连接数量。
    2,限制你代码里面的并发连接数量。
      

  5.   

    10楼和24楼 已经把解决方案说了
    将所有 线程的 插入数据库操作 全部委托到一个地方(我们是UI线程),然后插入队列,上锁(防止同时插入队列), 再就是楼上所说 再开一个线程专门用来处理数据, 但是注意要用委托,因为你开的这个插入数据的线程 是独立的,而数据表属于UI线程的, 我们是在这个线程里面用INVOKE方法 将操作同步到 UI线程里面。
       还有就是我感觉 你的这个数据表是UI线程的,就要使用委托和INVOKE方法。
       如果只是单独的 插入数据库,就没必要这样了,你可以将每个线程 看做一个类,每个类都包含一个插入数据操作,也是插入同一张表格(数据库表格,不是UI里面的显示表格控件), 这种情况 是不会死锁的,至少200台设备同时插入数据 我试过,没问题。
      

  6.   

    我说的是线程,请教大侠为何我插入时明显丢失数据,我只开20个线程(因为有20个连接终端),但是不同的是我的终端插入有如下循环
    for(int j = 0; j < _rtnStr.Length; j+2)
                        {
                            sqlCmd = "insert into tagvalue(tagdatetime, tagcode, tagval) values(?tagdatetime, ?tagcode, ?tagval)";
                            
                            //tagdatetime = DateTime.Now;
                            //tagcode = 实验室号;
                            //tagval = _rtnStr.Substring(j, 2);
                        }
    是不是因为循环插入造成独占表,使得其他线程插入数据丢失
      

  7.   

    我说的是线程,但是如大侠所说我开20线程同时插入表确实造成数据丢失了(有20个设备),为啥啊,是不是我在线程中循环插入数据造成线程独占表?使其他线程无法插入,数据丢失?
    for(int j = 0; j < _rtnStr.Length; j+2)
                        {
                            sqlCmd = "insert into tagvalue(tagdatetime, tagcode, tagval) values(?tagdatetime, ?tagcode, ?tagval)";
                            
                            //tagdatetime = DateTime.Now;
                            //tagcode = 实验室号;
                            //tagval = _rtnStr.Substring(j, 2);
                        }
      

  8.   

    批量加添  20个设备每产生一条数据 则   添加List<T> 中 如object locObj = new object();
    List<T> data = new List<T>();
    获取数据方法中lock(locObj)
    {
        data.Add(数据);
        if(data.Count>= 20)
         {
            //调用保存数据方法          InsertData(data);         data.Cler();
         }}
    //使用批量添加数据 SqlBulkCopy 类
    void InsertData(List<T> list)
    {
       
    }
      

  9.   

    既然你插入的数据列一样,为什么不先存进入一个table中
    然后用SqlBulkCopy入库呢
      

  10.   

    用不了那么复杂吧?
    在类里面声明一个全局对象private static readonly object locker = new object();
    ......
    ......
    然后在你的代码
    lock(locker) 

       rtn = cmd.ExecuteNonQuery();
    }
      

  11.   

    10楼和24楼 已经把解决方案说了
    将所有 线程的 插入数据库操作 全部委托到一个地方(我们是UI线程),然后插入队列,上锁(防止同时插入队列), 再就是楼上所说 再开一个线程专门用来处理数据, 但是注意要用委托,因为你开的这个插入数据的线程 是独立的,而数据表属于UI线程的, 我们是在这个线程里面用INVOKE方法 将操作同步到 UI线程里面。
       还有就是我感觉 你的这个数据表是UI线程的,就要使用委托和INVOKE方法。
       如果只是单独的 插入数据库,就没必要这样了,你可以将每个线程 看做一个类,每个类都包含一个插入数据操作,也是插入同一张表格(数据库表格,不是UI里面的显示表格控件), 这种情况 是不会死锁的,至少200台设备同时插入数据 我试过,没问题。 
      

  12.   

    死锁就是两个或多个线程抢一个对象,最后导致多线程卡住,用lock防止
      

  13.   

    数据库连接的死锁最好的解决办法,就是不同线程用不同的数据库连接对象去执行sql.