【发布时间】:2023-03-14 05:02:01
【问题描述】:
我们有一个用经典 ASP 编写的旧版 Web 应用程序,目前使用 MS Access 数据库作为其数据存储。通过 Jet OleDB 提供程序与数据库交互:
Provider=Microsoft.JET.OLEDB.4.0;Data Source=database.mdb
与大多数 Web 应用程序一样,CRUD 操作会定期在数据库上执行。
应用程序连接到数据库,执行insert、update、delete 或select 语句然后关闭连接。连接关闭后,我们可以立即重命名或移动 MS Access .mdb 文件而不受惩罚。多年来,我们一直在利用这种行为 - 这对于我们的用例来说是必要的,并且对我们很有帮助。
由于各种原因,我们正在用 SQLite 3 替换 MS Access 数据库。我们通过 ODBC 连接到 SQLite 版本。
与 SQLite 数据库的交互就像以前一样,即连接到数据库,发出 SQL 命令,关闭连接。
问题是 SQLite 数据库文件在连接关闭后保持锁定 60 秒。这可以防止我们重命名或移动数据库文件,因为很有可能在 60 秒内发生另一个连接,因此文件似乎被永久锁定。
我们在 Classic ASP 中创建了一个最小页面来说明行为:
Dim connectionString: connectionString = "DRIVER=SQLite3 ODBC Driver;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;FKSupport=0;NoCreat=1;Database=database.sqlite"
Dim con : Set con = CreateObject("ADODB.Connection")
con.Open connectionString
' Issue some CRUD commands here
con.Close
Set con = Nothing
Response.Write("We are here!!!!!")
为了确定导致锁定的原因,我们构建了一个VBScript 文件(使用上面显示的相同 SQLite 连接字符串)然后我们从命令行运行它(因此根本不涉及 IIS。)
在这种情况下,在连接后,发出任何CRUD 命令,然后关闭数据库,SQLite 文件可以立即访问。因此我们得出结论,IIS 7.5(或更准确地说是W3WP.exe)以某种方式对 SQLite 文件进行了锁定。事实上,如果我们停止网站的 App Pool,文件上的锁就会立即释放。
VBScript文件的代码如下:
Dim connectionString: connectionString = "DRIVER=SQLite3 ODBC Driver;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;FKSupport=0;NoCreat=1;Database=database.sqlite"
Dim con : Set con = CreateObject("ADODB.Connection")
con.Open connectionString
' Issue some CRUD commands here
WScript.Echo "Press [ENTER] to continue..."
' Read dummy input. This call will not return until [ENTER] is pressed.
WScript.StdIn.ReadLine
WScript.Echo "Done."
con.Close
Set con = Nothing
我们可以利用 IIS 中的某种设置来操作 SQLite 数据库,就像我们目前使用 MS Access 一样?
【问题讨论】:
-
如果它以前在 MSAccess DB 上工作过,您如何得出 IIS 有问题的结论?更有可能是 SQLite 驱动程序是导致该行为的原因,而不是 IIS。
-
@Lankymart 我已经编辑了我的问题,希望能更清楚地说明从 VBScript 文件内部连接到 SQLite 时不会导致文件锁定 60 秒。但是当连接到经典 ASP 文件中的 SQLite 时,会锁定文件 60 秒。两种情况都使用相同的驱动程序和连接字符串。
-
听起来你在做
conn.Close,但没有跟进Set conn = Nothing -
可能与连接池有关,尽管对于您使用的 SQLite 驱动程序,默认情况下禁用池。也许 IIS 只是在做自己的事情。发现此链接声称 IIS 仅在 60 秒后释放 ODBC 连接:knowledgebase.progress.com/articles/Article/…
-
@GordThompson 我们实际上是在发出
Set conn = Nothing命令。我编辑了问题以显示代码。
标签: sqlite ms-access iis asp-classic odbc