0

我有一个 WebService 可以从一些终端 (10) 更新我的访问表。当我尝试更新时,我从错误日志中收到此错误:

Could not Update; Currently locked

有些终端成功了,有些则没有。

我这样更新:

using (Conn = new OleDbConnection(Work_Connect))
         {
            Conn.Open();
            foreach (DataRow R in ds.Tables["MyCount"].Rows)
            {
                    U_ID = ID;
                    U_Bar = R["Bar"].ToString().Trim();
                    U_Qty = R["Qty"].ToString().Trim();
                    U_Des = R["Des"].ToString().Trim();

                    SQL  = "INSERT INTO MyTbl(ID,Bar,Qty,Des)VALUES('";
                    SQL += Convert.ToInt32(ID) + "','" + U_Bar + "','" + Convert.ToDouble(U_Qty) + "','" + U_Des + "')";
                    OleDbCommand Cmd2 = new OleDbCommand(SQL, Conn);
                    Cmd2.CommandText = SQL;
                    Cmd2.ExecuteNonQuery();
              }
           }
           GC.Collect();
           return true;
4

2 回答 2

1

MsAccess 对于多用户更新有严重的缺陷。Jet 引擎不是数据库服务器,它将根据文件系统锁定来管理并发。如果您的问题与 Web 服务有关,我会将更新移至服务器部分,并在那里实现同时请求的排队。因此,只有服务器,一个进程,才能访问 Access 数据。另一种选择是使用真正的数据库服务器来为您完成这项工作。SQL Server Express 是通常的选择,因为它易于集成,像啤酒一样免费,而且很可靠。

另外,如果你的问题总是来自同一个终端,即某些终端永远无法更新任何东西,请检查这些终端用户对数据库文件、锁定文件、数据库和锁定文件目录的文件访问权限。所有这些都需要写权限。

于 2013-06-02T09:01:17.840 回答
1

建议:

  1. 将您的查询转换为参数化查询,以避免任何潜在的引用异常。(您将文本转换为数字,然后在 SQL 语句中将它们括在单引号中。这没有任何意义。)

  2. 不要在每次调用时强制进行垃圾收集。根据此处的 MSDN 文章:“可以通过调用 Collect 来强制进行垃圾收集,但大多数情况下,应该避免这样做,因为它可能会产生性能问题。”

尝试这样的事情:

using (Conn = new OleDbConnection(Work_Connect))
{
    Conn.Open();
    foreach (DataRow R in ds.Tables["MyCount"].Rows)
    {
        U_ID = ID;
        U_Bar = R["Bar"].ToString().Trim();
        U_Qty = R["Qty"].ToString().Trim();
        U_Des = R["Des"].ToString().Trim();

        SQL  = "INSERT INTO MyTbl (ID,Bar,Qty,Des) VALUES (?,?,?,?)";
        using(OleDbCommand Cmd2 = new OleDbCommand(SQL, Conn))
        {
            // Cmd2.CommandText = SQL;  redundant, the 'new' set the .CommandText
            Cmd2.Parameters.AddWithValue("?", Convert.ToInt32(ID));
            Cmd2.Parameters.AddWithValue("?", U_Bar);
            Cmd2.Parameters.AddWithValue("?", Convert.ToDouble(U_Qty));
            Cmd2.Parameters.AddWithValue("?", U_Des);
            Cmd2.ExecuteNonQuery();
        }
    }
    Conn.Close();
}
// GC.Collect();  // disabled for test purposes
return true;
于 2013-06-02T12:12:57.310 回答