SQLite: '无法打开数据库文件'包含多个命令的事务例外
本文关键字:命令 事务 包含多 数据库 SQLite 文件 | 更新日期: 2023-09-27 18:02:19
我有以下(简化)代码:
IDbConnection connection = new SQLiteConnection(GetConnectionString());
if (connection.State == ConnectionState.Closed)
connection.Open();
using (IDbTransaction transaction = connection.BeginTransaction())
{
using (IDbCommand cmd = transaction.Connection.CreateCommand())
{
cmd.CommandText = "DELETE FROM Records2 WHERE ClientIndex = @ClientIndex";
AddParameter(cmd, "@ClientIndex", DbType.Int32, clientIndex);
cmd.ExecuteNonQuery();
}
using (IDbCommand cmd = transaction.Connection.CreateCommand())
{
cmd.CommandText = "INSERT INTO Records2(ClientIndex, CandidateIndex, Name)";
cmd.CommandText += " VALUES(@ClientIndex, @CandidateIndex, @Name)";
AddParameter(cmd, "@ClientIndex", DbType.Int32, clientIndex);
IDbDataParameter pIndex = AddParameter(cmd, "@CandidateIndex", DbType.Int32, null);
IDbDataParameter pName = AddParameter(cmd, "@Name", DbType.AnsiString, null);
int index = 0;
foreach (Record record in records)
{
pIndex.Value = index++;
pName.Value = record.Name;
cmd.ExecuteNonQuery();
}
}
using (IDbCommand cmd = transaction.Connection.CreateCommand())
{
cmd.CommandText = "UPDATE Records SET Status = @Status, UpdateDate = @UpdateDate WHERE ClientIndex = @ClientIndex";
AddParameter(cmd, "@ClientIndex", DbType.Int32, clientIndex);
AddParameter(cmd, "@Status", DbType.Byte, status);
AddParameter(cmd, "@UpdateDate", DbType.DateTime, DateTime.Now);
cmd.ExecuteNonQuery();
}
transaction.Commit();
}
connection.Close();
:
private IDbDataParameter AddParameter(IDbCommand command, string paramName, DbType type, object value)
{
IDbDataParameter parameter = command.CreateParameter();
parameter.ParameterName = paramName;
parameter.DbType = type;
if (value != null)
parameter.Value = value;
else
parameter.Value = DBNull.Value;
command.Parameters.Add(parameter);
return parameter;
}
所有的ExecuteNonQueries都可以正常工作,除了最后一个。在我的机器(运行xp)上,我得到以下异常,但在其他机器(运行windows 7)上,它可以正常工作,具有相同的代码和相同的数据库文件。
SQLiteException (0x80004005): Unable to open the database file
System.Data.SQLite.SQLite3.Reset(SQLiteStatement stmt) +375
System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt) +199
System.Data.SQLite.SQLiteDataReader.NextResult() +226
System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave) +87
System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior) +38
System.Data.SQLite.SQLiteCommand.ExecuteNonQuery() +39
我尝试在连接字符串中使用JournalMode = Perist,并且我从杀毒软件中排除了包含数据库文件的目录,但没有任何帮助。
我使用的是3.5框架,我的System.Data.SQLite版本是1.0.66.0。
有什么想法吗?
提前感谢,
Marc我在1.0.87和1.0.89中遇到了同样的问题,最终(在procmon的帮助下)找到了原因。这实际上是一个误导性的错误信息,因为它不是数据库文件本身被拒绝访问,而是SQLite语句日志。
虽然在正确的位置创建了SQLite数据库文件和日志,并且该文件夹的权限允许访问Everyone,但SQLite仍然使用%TEMP%
作为其语句日志。%TEMP%
映射到运行服务的身份的用户配置文件下的临时文件夹。因此,当一个非特权客户端身份访问服务(并在服务内部和背后进行模拟)时,该非特权身份不能创建用于语句日志的etilqs_XXXXX
临时文件夹。
我的解决办法是在SQLiteConnection
s上设置PRAGMA
:
PRAGMA temp_store_directory='<same_path_as_the_database_file>'
我将我的System.Data.SQLite.dll从Robert Simpson编写的1.0.66.0版本(http://sqlite.phxsoftware.com)升级到SQLite开发团队编写的1.0.74.0版本(http://system.data.sqlite.org),这似乎解决了问题。
我知道这个问题是旧的,但我昨天刚刚有同样的问题,正在寻找答案。在我的例子中,我的开发环境是正常的,而生产是失败的。问题是在我的生产网站的下面一行。配置:
<connectionStrings>
<add name="SalesForceConnection"
connectionString="metadata=res://SalesForceDataModel.csdl|res://SalesForceDataModel.ssdl|res://SalesForceDataModel.msl;
provider=Devart.Data.Salesforce;
provider connection string="
User Id=myUserId;
Password=myPassword;
Security Token=myToken;
Persist Security Info=True;
Host=login.salesforce.com;
Data Cache=c:'projects'salesforce'1.db;
Metadata Cache=c:'projects'salesforce'1_Metadata.db""
providerName="System.Data.EntityClient" />
</connectionStrings>
数据缓存和元数据缓存都指向我的开发环境中的目录。由于连接字符串很长,我错过了这2个设置。我将目录更改为生产服务器上的目录,并且一切正常。