我有一个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;
答案 0 :(得分:1)
MsAccess在多用户更新方面存在严重缺陷。 Jet引擎不是数据库服务器,它将根据文件系统锁定来管理并发。如果您的问题在于Web服务,我会将更新移动到服务器部分,并在那里实现对同时请求的排队。因此,只有服务器(一个进程)才能访问Access数据。另一种选择是使用真正的数据库服务器来完成这项工作。 SQL Server Express是常用选项,因为它易于集成,它在啤酒中是免费的,而且非常可靠。
此外,如果您的问题始终来自相同的终端,也就是说,某些终端永远无法更新任何内容,请检查这些终端的用户对数据库文件,锁定文件以及数据库和锁定文件的文件访问权限目录。所有人都需要写权利。
答案 1 :(得分:1)
建议:
将您的查询转换为参数化查询,以避免引用带来任何可能的陌生感。 (您正在将文本转换为数字,然后将它们用SQL语句中的单引号括起来。这没有任何意义。)
不要在每次通话时强制进行垃圾回收。根据MSDN文章here:“可以通过调用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;