我有以下代码需要大约一个小时来运行几十万行:
public void Recording(int rowindex)
{
using (OleDbCommand cmd = new OleDbCommand())
{
try
{
using (OleDbConnection connection = new OleDbConnection(Con))
{
cmd.Connection = connection;
connection.Open();
using (OleDbTransaction Scope = connection.BeginTransaction(SD.IsolationLevel.ReadCommitted))
{
try
{
string Query = @"UPDATE [" + SetupAction.currentTable + "] set Description=@Description, Description_Department=@Description_Department, Accounts=@Accounts where ID=@ID";
cmd.Parameters.AddWithValue("@Description", VirtualTable.Rows[rowindex][4].ToString());
cmd.Parameters.AddWithValue("@Description_Department", VirtualTable.Rows[rowindex][18].ToString());
cmd.Parameters.AddWithValue("@Accounts", VirtualTable.Rows[rowindex][22].ToString());
cmd.Parameters.AddWithValue("@ID", VirtualTable.Rows[rowindex][0].ToString());
cmd.CommandText = Query;
cmd.Transaction = Scope;
cmd.ExecuteNonQuery();
Scope.Commit();
}
catch (OleDbException odex)
{
MessageBox.Show(odex.Message);
Scope.Rollback();
}
}
}
}
catch (OleDbException ex)
{
MessageBox.Show("SQL: " + ex);
}
}
}
它按预期工作,但是今天我的程序在运行查询时崩溃了(在for循环中,rowindex是数据表的索引),计算机崩溃,当我重新启动程序时,它说:< / p>
多步OleDB操作生成错误:后跟我的连接字符串。
发生的事情是数据库是完全不可交互的,即使是微软访问的恢复方法似乎也无法帮助到这里。
我读过这可能是因为数据库的数据结构与预期的数据结构有所不同。我的问题是,我如何防止这种情况,因为我无法确定我的程序是否突然停止运行。
我可能有办法以某种方式重组它,也许有一个我不知道的功能。可能是在发生崩溃时发送了一些空查询,但我不知道如何阻止它。
答案 0 :(得分:2)
Jet / ACE数据库引擎已经尝试避免损坏并自动从灾难性事件中恢复(连接丢失,计算机崩溃)。通过完全提交(或丢弃)多个操作,事务可以进一步防止不一致的数据。但最终可能会出现一些巧合的系统故障,这可能会终止某个关键写入位置的操作,从而在数据库文件中产生严重的不一致。定期和及时备份是整体解决方案的一部分。对于非常长的操作,可能需要在操作之前制作整个数据库文件的自动副本。
否则,一个极端的选择是
UPDATE LocalTable INNER JOIN LinkedTable ON LocalTable.UpdateID = LinkedTable.ID SET LinkedTable.Data = LocalTable.Data
此过程的好处是,从一个Access表中更新一个Access表的单个查询可能非常快,可能比代码中的多个更新操作快得多。这可以降低更新代码中的错误对数据库产生负面影响的可能性。这当然不能完全消除可能影响数据库的随机计算机崩溃,但减少执行多个连接和更新查询的时间可能会降低它的可能性。
答案 1 :(得分:1)
我认为你的catch块是错误的,因为如果你得到OleDbException以外的异常,你将不会回滚事务
public void OnApplicationPause(bool paused) {
if(paused) {
// Game is paused, start service to get notifications
} else {
// Game is unpaused, stop service notifications.
}
即异常,而不是 OleDbException 。例外情况可能来自任何地方,而不一定是Ole DB,你仍然希望回滚到目前为止你所做的一切。
话虽如此,如果你有几十万行,我会认真考虑批量更新,并且每次迭代只需处理几千个每次迭代的交易
就交易行为而言,主要问题是:您是否真的想要回滚到目前为止已经更新的一切以防发生故障,或者只是重试/继续您的位置离开?如果答案是您要重试/继续,那么您可能希望创建一个try
{
// ...
Scope.Commit();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
Scope.Rollback();
}
表或类似的...以及每次迭代所需的所有信息