在您需要提交之前或Access / Jet抛出错误之前,您可以在Access事务中执行的插入数量是否有限制?
我目前正在运行以下代码,希望确定这个最大值是多少。
OleDbConnection cn =
new OleDbConnection(
@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\temp\myAccessFile.accdb;Persist Security Info=False;");
try
{
cn.Open();
oleCommand = new OleDbCommand("BEGIN TRANSACTION", cn);
oleCommand.ExecuteNonQuery();
oleCommand.CommandText =
"insert into [table1] (name) values ('1000000000001000000000000010000000000000')";
for (i = 0; i < 25000000; i++)
{
oleCommand.ExecuteNonQuery();
}
oleCommand.CommandText = "COMMIT";
oleCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
}
finally
{
try
{
oleCommand.CommandText = "COMMIT";
oleCommand.ExecuteNonQuery();
}
catch{}
if (cn.State != ConnectionState.Closed)
{
cn.Close();
}
}
当我在一个未通信的事务中达到2,333,920个插入时,我在生产应用程序上收到的错误是:“文件共享锁定计数已超出。增加MaxLocksPerFile注册表项”。禁用事务修复了此问题。
答案 0 :(得分:4)
我刚刚在.accdb数据库的表上成功创建并提交了5,000,000个插入事务。一个显着的区别是我没有直接发出BEGIN TRANSACTION
和COMMIT
语句,而是使用OleDbTransaction
对象:
cmd.CommandText =
@"INSERT INTO Companies (ID, CompanyName) VALUES (?, ?)";
cmd.Parameters.Add("?", OleDbType.Integer);
cmd.Parameters.Add("?", OleDbType.VarWChar, 255);
cmd.Prepare();
OleDbTransaction tran = con.BeginTransaction();
cmd.Transaction = tran;
for (int i = 1; i <= 5000000; i++)
{
if ((i % 100) == 0)
{
Console.WriteLine(i.ToString());
}
cmd.Parameters[0].Value = i;
cmd.Parameters[1].Value = "Company" + i.ToString();
cmd.ExecuteNonQuery();
}
tran.Commit();
修改评论<评论
成功创建并提交10,000,000插入事务,并验证.Rollback()
确实工作(好建议,neoistheone!)后,我检查了IsolationLevel
交易。 ACE.OLEDB驱动程序的默认IsolationLevel
显然是ReadCommitted
,根据MSDN表示:
在读取数据时保持共享锁以避免脏读,但可以在事务结束之前更改数据,从而导致不可重复的读取或幻像数据。
维基百科很好地描述了那些不同的“阅读现象”here。
也许如果我要指定更严格的隔离级别(如Serializable
),我可能会遇到问题中描述的锁定限制,尽管因为这些都是INSERT操作,所以ACE.OLEDB驱动程序只需“隐藏“来自所有其他连接的插入,直到它们被提交。
编辑重新:效果
由于在事务中包装大量INSERT操作的一个相当常见的原因是为了更快地完成它们,我测试了一批包含和不包含OleDbTransaction
的100,000个插入。 (在两种情况下都使用了准备好的声明。)如果没有OleDbTransaction
,批处理大约需要36秒才能完成。使用默认隔离级别OleDbTransaction
启用ReadCommitted
会将已用时间减少到大约23秒。
答案 1 :(得分:3)
是的,实际上有一个限制。你清楚地达到了它。每Microsoft's documentation:
如果执行事务所需的锁数超过每个文件的最大锁数,则会发生错误。
在该链接上有几个解决方法。第二个更现实,它暂时改变了最大锁。