如何锁定 Access 数据库以防止写入

Posted

技术标签:

【中文标题】如何锁定 Access 数据库以防止写入【英文标题】:How to lock an Access database against writes 【发布时间】:2015-08-10 20:53:21 【问题描述】:

我找不到这个问题的答案,也很难通过实验来确定。

我正在使用带有DBIDBD::ODBC 的Perl 将多个表批量加载到Microsoft Access 数据库中。所有查询都在一个事务中完成,该事务在加载结束时提交(或在错误时回滚)。数据库处于多用户环境中。

理想情况下,我想锁定数据库,以便在我的加载过程中没有其他进程可以进行任何更改,加载过程只持续大约一分钟,并且每天运行一次。这很重要的一个原因是,有时在加载过程中我必须查看@@identity 才能获取我刚刚插入的记录的自动编号 ID。

我的记录锁定设置应该是什么?我目前正在使用

Default Open Mode – Shared
Default record locking – Edited Record

事务是否会在提交之前锁定整个数据库以防止写入?如果没有,我有没有办法使用DBI::ODBC 锁定所有写入?

通过实验,我可以看出 Access 正在为我做一些锁定,但我不能确定这是完全锁定。

更新:代码如下所示:

#!/usr/bin/perl -w
use strict;
use DBI; #database connection library

#open database connection
my $path='C:\Users\me\Desktop\mydb.accdb'; 
my $datasource = "Driver=Microsoft Access Driver (*.mdb, *.accdb);DBQ=$path";


my $dbh = DBI->connect("dbi:ODBC:$datasource", '', '',
    
            PrintError => 0,
            PrintWarn  => 1,
            RaiseError => 1,
            AutoCommit => 0,  
        ) || die "Error connecting: $!";



#Then I do various database operations.  Example:

#insert into database:
my $sth_insert = $dbh->prepare(qq
INSERT INTO table1 (field1, field2)
values (?,?)
) 

$sth_insert->execute($value1,$value2);  

#get back the autonumber ID: last_insert_id(undef,undef,undef,undef) is not supported
my $sqlQuery = 'SELECT @@IDENTITY';
my $sth_select = $dbh->prepare( $sqlQuery );
$sth_select->execute;
my $newId = $sth_select->fetchrow_array; #will this be reliable in multi-user environment with my settings?

#Then I commit the transaction:
$dbh->commit or die $DBI::errstr;

整个事情都在一个 eval 语句中,所以如果它抛出一个错误,我会回滚而不是提交。

如果可以的话,我宁愿锁定所有内容(读取和写入)。

【问题讨论】:

请出示您的代码。您确定要仅阻止写访问吗?如果未解锁,从数据库读取的数据可能会返回虚假数据。您要更新多个表吗? @Borodin - 没错,如果可以的话,我宁愿阻止所有的读写。我用代码编辑了帖子。感谢您的帮助。 【参考方案1】:

我认为你没有问题。您的进程附加的记录的ID不会被另一个进程窃取。

【讨论】:

我编辑了代码以添加插入语句并检查@@identity。考虑到我的设置,这也安全吗?有没有办法使用 Perl 显式锁定整个数据库以防止读写?如果可以的话,我更愿意这样做。谢谢。 我知道的唯一选择是独占打开数据库,但这要求没有其他进程打开文件。 只有少数用户,加载只需要一分钟,所以这可能会奏效。我将研究如何使用带有 MS Access 驱动程序的 perl dbi:odbc 进行独占锁定,但如果您碰巧知道,也许您可​​以为我指明正确的方向。 对不起,没有。我对 Perl 的了解为零。

以上是关于如何锁定 Access 数据库以防止写入的主要内容,如果未能解决你的问题,请参考以下文章

在 MS Access 中禁用 F11 键以防止打开导航窗格

如何在文件写入时防止其他人读取/写入文件

MS Access 数据库被 Python 锁定

如何使用信号量锁定表?

站点关闭时防止打开文件锁定

防止共享哈希表中的数据竞争