wpf 无法更新;当前锁定

xienkqul  于 2023-04-13  发布在  其他
关注(0)|答案(2)|浏览(203)

我正在使用后台进程将数据插入到表中。当我尝试将数据插入到表中时,我得到以下错误:
无法更新;目前锁定。
在我的例子中,这个表(JobsTemp)在另一个进程的操作中没有使用任何where,但是应用程序的其他进程正在使用同一个数据库的表。

  • 是什么导致了这个bug?
  • 我可以检查数据库是否被锁定吗?

我们试图用WPF应用程序将数据插入MS Access 2003数据库。那么如何通过编程解决这个问题呢?

private static string dbFile =
    Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
        + "\\AppData\\LocalAccess.mdb";
private static string ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
    + dbFile + ";";
public bool SalesTPJob_Insert_InAccessDB(DataTable DT)
{
    bool flag = true;
    try
    {
        if (DT != null)
        {
            if (DT.Rows.Count > 0)
            {
                string deleteQuery = "DELETE  FROM JobsTemp";
                DeleteUpdateRecordFromTable(deleteQuery);
                string SQL = "SELECT top 1 * FROM JobsTemp";
                string INSERT = "INSERT INTO " 
                    + "JobsTemp([JobId],[CustomerId],[JobName],[JobAddress],[City]," 
                    + "[State],[Zip],[IsExisting],[Area])"
                    + " VALUES (@JobId,@CustomerId,@JobName,@JobAddress,@City,@State," 
                    + "@Zip,1,@Area)";

                OleDbConnection OleConn = new OleDbConnection(ConnString);
                OleDbDataAdapter OleAdp = new OleDbDataAdapter(SQL, OleConn);

                OleAdp.InsertCommand = new OleDbCommand(INSERT);

                OleAdp.InsertCommand.Parameters.Add("@JobId", OleDbType.VarChar, 
                    1008, "JobId");
                OleAdp.InsertCommand.Parameters.Add("@CustomerId", OleDbType.VarChar, 
                    1008, "CustomerId");
                OleAdp.InsertCommand.Parameters.Add("@JobName", OleDbType.VarChar, 
                    1008, "JobName");
                OleAdp.InsertCommand.Parameters.Add("@JobAddress", OleDbType.VarChar,  
                    1008, "JobAddress");
                OleAdp.InsertCommand.Parameters.Add("@City", OleDbType.VarChar,  
                    1008, "City");
                OleAdp.InsertCommand.Parameters.Add("@State", OleDbType.VarChar,  
                    1008, "State");
                OleAdp.InsertCommand.Parameters.Add("@Zip", OleDbType.VarChar,  
                    4000, "Zip");
                OleAdp.InsertCommand.Parameters.Add("@Area", OleDbType.VarChar,  
                    1008, "Area");

                OleAdp.InsertCommand.Connection = OleConn;
                OleAdp.InsertCommand.Connection.Open();
                int i = OleAdp.Update(DT);
                OleAdp.InsertCommand.Connection.Close();
            }
        }
    }
    catch (Exception ex)
    {
        LogFile(ex.ToString());
        flag = false;
    }
    return flag;
}

JobsTemp未在任何其他进程中使用。

public int DeleteUpdateRecordFromTable(string query)
    {
        using (OleDbConnection OleConn = new OleDbConnection(ConnString))
        {
            int i = 0;
            try
            {
                OleConn.Open();
                OleDbCommand ac = new OleDbCommand(query, OleConn);
                i = ac.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                OleConn.Close();
                LogFile(ex.ToString());
            }
            return i;
        }
    }
zu0ti5jz

zu0ti5jz1#

我敢打赌,DeleteUpdateRecordFromTable会在table上留下一把锁。
select应该没问题,因为它没有改变任何东西(这取决于你的数据库是否设置了乐观锁)。然而,insert可能被来自delete的锁卡住了。
要在执行插入操作之前检查表是否被锁定,可能必须使用oledbTransaction并为deleteinsert设置适当的事务;然后根据需要处理try/catch中的问题。

wmvff8tz

wmvff8tz2#

我最近遇到了这个问题,我认为问题是你在执行查询后没有关闭连接,就像@BIBD在评论中提到的那样。你应该在i = ac.ExecuteNonQuery();后面添加OleConn.Close();。现在只有当出现异常时才会关闭连接。
你还应该在你的代码周围添加一个锁,这将使它成为线程安全的。最后,你应该通过一个方法运行所有的数据库命令,这将确保一次只运行一个命令,并且每次连接都正确关闭:

public bool ExecuteNonQuery(IDbCommand command)
{
    if (command == null)
        return false;

    try
    {
        using (IDbConnection connection = GetConnection())
        {
            int rowsAffected = 0;

            try
            {
                lock (_executeLock)
                {
                    connection.Open();
                    command.Connection = connection;

                    rowsAffected = command.ExecuteNonQuery;

                    connection.Close();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message + " in Database.ExecuteNonQuery with '" + command.CommandText + "'");
            }

            return rowsAffected > 0;
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message + " in Database.ExecuteNonQuery while opening connection.");
    }
}

相关问题