防止 IIS 对 SQLite 数据库文件保持文件锁定
Preventing IIS from keeping a file lock on a SQLite database file
我们有一个用 Classic 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 秒内发生另一个连接,因此该文件似乎被永久锁定。
我们在经典 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 文件持有某种锁定。事实上,如果我们停止网站的应用程序池,文件上的锁会立即释放。
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 中是否有某种设置可供我们使用,使我们能够像目前使用 MS Access 一样操作 SQLite 数据库?
使用 CH Werner SQLite ODBC Driver 您无法关闭连接池。驱动程序中有处理 SQL_ATTR_CONNECTION_POOLING
属性的代码,但从未使用过该属性。这意味着它将默认使用连接池。
停止 IIS 锁定数据库将涉及修改 DLL 以包含 ConnectionPooling=True/False 或 CPTimeout=n 这样我们就可以将适当的值发送到 SQLSetEnvAttr
函数。
我在发布原始问题大约一年后重新访问了这个问题,因为一位同事实际上发现了对我们有用的解决方案,也许它会对其他人有所帮助。
有效的解决方案是对注册表进行一些更改。这与 CH Werner SQLIte ODBC Driver 无关。事实上,我们与 CH Werner 本人进行了电子邮件对话,他确认驱动程序不会像我们描述的那样影响数据库的锁定。
解决方法是对注册表进行如下修改:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{c8b522cb-5cf3-11ce-ade5-00aa0044773d}]
@="MSDASQL"
"OLEDB_SERVICES"=dword:fffffffe
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\{c8b522cb-5cf3-11ce-ade5-00aa0044773d}]
@="MSDASQL"
"OLEDB_SERVICES"=dword:fffffffe
如果您将上述注册表更改放入文件扩展名为 .reg 的文件中,您将能够 double-click 在 windows 资源管理器中将其 double-click进行更改。
一旦注册表有了这些设置,IIS
将 不会 在连接关闭后锁定 SQLite
数据库文件 60 秒。
希望这会帮助遇到此问题的其他人。
我们有一个用 Classic 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 秒内发生另一个连接,因此该文件似乎被永久锁定。
我们在经典 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 文件持有某种锁定。事实上,如果我们停止网站的应用程序池,文件上的锁会立即释放。
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 中是否有某种设置可供我们使用,使我们能够像目前使用 MS Access 一样操作 SQLite 数据库?
使用 CH Werner SQLite ODBC Driver 您无法关闭连接池。驱动程序中有处理 SQL_ATTR_CONNECTION_POOLING
属性的代码,但从未使用过该属性。这意味着它将默认使用连接池。
停止 IIS 锁定数据库将涉及修改 DLL 以包含 ConnectionPooling=True/False 或 CPTimeout=n 这样我们就可以将适当的值发送到 SQLSetEnvAttr
函数。
我在发布原始问题大约一年后重新访问了这个问题,因为一位同事实际上发现了对我们有用的解决方案,也许它会对其他人有所帮助。
有效的解决方案是对注册表进行一些更改。这与 CH Werner SQLIte ODBC Driver 无关。事实上,我们与 CH Werner 本人进行了电子邮件对话,他确认驱动程序不会像我们描述的那样影响数据库的锁定。
解决方法是对注册表进行如下修改:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{c8b522cb-5cf3-11ce-ade5-00aa0044773d}]
@="MSDASQL"
"OLEDB_SERVICES"=dword:fffffffe
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Wow6432Node\CLSID\{c8b522cb-5cf3-11ce-ade5-00aa0044773d}]
@="MSDASQL"
"OLEDB_SERVICES"=dword:fffffffe
如果您将上述注册表更改放入文件扩展名为 .reg 的文件中,您将能够 double-click 在 windows 资源管理器中将其 double-click进行更改。
一旦注册表有了这些设置,IIS
将 不会 在连接关闭后锁定 SQLite
数据库文件 60 秒。
希望这会帮助遇到此问题的其他人。