【发布时间】:2020-11-24 13:01:55
【问题描述】:
我发现当我使用 OdbcConnection 更新 Jet SQL 数据库时,c# 代码很快完成,但数据库在数百毫秒内没有更新。因此,当我在更新数据库的代码完成后立即读取数据库时,我正在读取旧数据。
在一个特定的 UPDATE 之后,我会立即重新加载一个网格,它会显示未更改的数据,除非我暂停。 SQL 命令相当简单,例如: UPDATE MyTable SET MyField = 3 WHERE ID = 3000
using (var connection = new OdbcConnection(connectionString))
{
connection.Open();
using (var command = new OdbcCommand(SQLText, connection))
{
command.Parameters = SQLParams;
int dummy = command.ExecuteNonQuery();
//System.Threading.Thread.Sleep(800);
}
}
如果我取消注释 Sleep 行,之后会读取更新的数据,否则会读取旧数据。
我正在使用本地数据库运行,所以并不是其他用户让数据库忙。
即使应用程序在更新后终止并且另一个应用程序立即读取数据,另一个应用程序也在读取旧数据。这让我认为它是 ODBC 功能(而不是 OdbcConnection 本身)中固有的东西,它不会立即处理 SQL。
我可以立即处理 SQL 吗?
或者,我可以询问 ODBC 以查找处理完成的时间吗?
【问题讨论】:
-
这可能是共享问题。您如何尝试读回数据? using 块正在处理命令和连接。在处理连接之前,文件被 Windows 锁定,因此您可以在只读模式下获得数据的副本。
-
@jdweng 感谢您的想法。在更新的 exe 关闭后,我正在通过不同的 OdbcConnection 或从不同的 exe 读取数据。在这两种情况下,我都发现了陈旧的数据。我尝试在 UPDATE 之后添加一个 Dispose 和新的 OdbcConnection(在同一个 exe 中读取的连接上),但问题仍然存在。当然,在更新的 exe 关闭后从不同的 exe 读取意味着更新 exe 中的所有内容在仍然读取陈旧数据之前已关闭和处置。
-
如果您有主键,则需要检查虚拟值是否为零。更新时为零表示密钥不在数据库中,您必须进行插入。当您执行插入并且 dummy 为零时,密钥已在数据库中,您需要进行更新。
-
@jdweng UPDATE 的虚拟值为 1(报告为已更新的记录数)。而且记录确实最终会更新,只是在 ExecuteNonQuery 完成时还没有完成,它是 500ms - 800ms 之后
-
我使用 JET 和 ODBC 已经很长时间了,但从未见过这种类型的结果。我看到的唯一问题是共享发生时。 JET 并不意味着共享(或并行处理)。您使用的是什么类型的数据库(扩展)?文件在哪里?如果文件有多大?如果你得到一个 1 的虚拟值,那么数据就被写入了。所以要么是其他东西改变了这个值,要么你不是从同一个位置读取。我还看到了数据库损坏且数据未正确保存的情况。使用 JET,数据库可能会严重碎片化或损坏。