使用C#的Mysql上的DeadLock - “超出锁定等待超时;尝试重启事务”

时间:2014-01-15 13:57:43

标签: c# mysql sql singleton deadlock

我们让这个类像SingleTon一样用来返回相同的连接和事务(隔离级别读取提交)(我们使用CRUD):

public class SharedDbMySQL : DatabaseMySQL
{
    private static DatabaseMySQL sConn;

    private SharedDbMySQL()
    {
    }

    public static DatabaseMySQL GetInstance()
    {
        return GetInstance(TipoDados.Dados);
    }

    public static DatabaseMySQL GetInstance(TipoDados OpcoesBD)
    {
        if (sConn == null)
            sConn = new DatabaseMySQL(OpcoesBD);
        return sConn;
    }
}

使用SQL(微软)...错误不会发生...只有Mysql。 我们首先插入“NotaFiscalEntrada”...... 在我们在这个方法上插入这个“NotaFiscalEntrada”的产品之后(我们在这里有错误):

public static void InsereAtualizaNotaFiscalEntradaProduto(List<nf_entrada_produto> entity, int IDNFEntrada, bool SharedConnection, bool LastOperation)
    {
        DatabaseMySQL db;
        MySqlCommand cmd = new MySqlCommand();

        if (SharedConnection)
            db = SharedDbMySQL.GetInstance();
        else
            db = new DatabaseMySQL();

        try
        {
            cmd.Connection = db.Conn;
            cmd.Transaction = db.BeginTransaction();
            ONF_Entrada_Produto OpNFProduto = new ONF_Entrada_Produto(cmd);
            foreach (nf_entrada_produto Item in entity)
            {
                Item.ValorICMSST = 0;
                Item.IDNFEntrada = IDNFEntrada;
                Item.IDEmpresa = BusinessLogicLayer.ObjetosGlobais.DadosGlobais.EmpresaGlobal.ID;
                if (Item.ID == 0)
                {
                    if (!OpNFProduto.Add(Item))
                        throw OpNFProduto.LastError;
                }
                else
                {
                    if (!OpNFProduto.Update(Item))
                        throw OpNFProduto.LastError;
                }
            }

            if (LastOperation || !SharedConnection)
            {
                db.CommitTransaction();
                db.Disconnect();
            }
        }
        catch (Exception ex)
        {
            db.RollBackTransaction();
            db.Disconnect();
            throw ex;
        }
    }

错误是我们插入产品时(上面的代码) “超出锁定等待超时;尝试重新启动事务”。 我们发现了一些关于死锁的事情......连接的丢失可能是错误,如何解决?我认为这是一个服务器错误?谢谢大家。

1 个答案:

答案 0 :(得分:0)

问题出现在METHODS上...我再次创建了一个新的连接而没有从单例中取出它...... 并且数据库使表死锁,其他连接也试图改变它......并且存在问题。

cmd.Connection = new db.Connect();
cmd.Connection = db.Conn;

替换为

cmd.Connection = db.Conn;

类db(singleton)内部:

MySqlConnection conn;

public MySqlConnection Conn
        {
            get
            {
                if ((conn == null) || (conn.State == System.Data.ConnectionState.Closed))
                {

                    Connect();
                }

                return conn;
            }
            set
            {
                conn = value;
            }
        }

public override void Connect()
        {
            RetornaDadosIniParaClasse();
            conn = new MySqlConnection(StringConnection);

            try
            {
                conn.Open();

                if (conn.State == System.Data.ConnectionState.Closed)
                {
                    throw new AccessDatabaseException("Conexão com o banco de dados firebird fechada");
                }
            }
            catch (Exception ex)
            {
                throw new AccessDatabaseException(ex.Message);
            }
        }

它耗费了大量时间,因为很难看出错误......我们为此找到了很多东西。