如何获取firebird数据库的独占锁以执行架构更改?

时间:2011-02-15 22:23:11

标签: c# sql firebird

更具体地说,我正在使用firebird 2.1和DDEX Provider for visual studio,我正在使用c#。

我有一种情况,我正在尝试从c#向数据库应用架构更改,以“更新”我的数据库。在此过程中,我从firebird获得以下异常:

FirebirdSql.Data.FirebirdClient.FbException:不成功的元数据更新对象INDEX正在使用中

我将此解释为一个容易出现问题,其中有另一个进程同时访问数据库。我不知道这是certian的原因,但它“似乎”是最可能的情况。我认为它可能与删除和添加约束有关,因为它们不可添加,因为约束不正确,但我能够在本地系统上运行命令而不会出现错误,而不是在客户端站点上。无论如何,我目前使用隔离级别“Serializable”将一些命令包装到一个事务中,并立即将它们全部提交。由于这是升级,因此可以根据需要阻止所有其他用户。

示例:

// note connection is pre-defined as a FbConnection, connected to the Database in question

FbTransaction transaction = Connection.BeginTransaction( IsolationLevel.Serializable );

// quite a bit of stuff gets done here, this is a sample
// I can run all the commands in this section in the isql tool and commit them all at once
// without error.  NOTE: I have not tried to run them all on the client enviroment, and likely can't

string commandString = "ALTER TABLE Product DROP CONSTRAINT ProductType;";
FbCommand command = new FbCommand(commandString, Connection, transaction);
command.ExecuteNonQuery();

commandString = "ALTER TABLE Product ADD CONSTRAINT ProductType " +
                "FOREIGN KEY ( TypeID ) REFERENCES Type ( TypeID ) " +
                "ON UPDATE CASCADE ON DELETE NO ACTION;";
command.CommandText = commandString;
command.ExecuteNonQuery();

// other commands include: 
// creating a new table
// creating 3 triggers for the new table

// commit the transaction
// this particular line actually "seems" to throw the exception mentioned

transaction.Commit();

我的想法是尝试使用指定事务的“手动”方式来获得对表的更多独占访问权限,但我似乎无法让它工作,因为我不明白将会是什么意志不能一起工作。

示例:

// Try to use FbTransactionOptions instead
// this statement complains about invalid options block when executing
FbTransaction transaction = Connection.BeginTransaction(
            FbTransactionOptions.Consistency |
            FbTransactionOptions.Exclusive |
            FbTransactionOptions.Wait |
            FbTransactionOptions.Write |
            FbTransactionOptions.LockWrite |
            FbTransactionOptions.NoRecVersion
            );

无论如何,我的问题是,我如何获得对数据库的独占访问权来执行这些更新?我几乎希望能够把所有人都赶走,然后去做。帮助和建议非常丰富!!!


新信息: 我能够将数据带到我的本地,现在错误显示为:

FirebirdSql.Data.FirebirdClient.FbException:违反表格“TYPE”上的FOREIGN KEY约束“INTEG_72”

这很清楚,所以我会解决这个问题并在网站上进行尝试。


这似乎解决了这个问题 所以,总而言之,我在客户端系统上有一个例外:

FirebirdSql.Data.FirebirdClient.FbException:不成功的元数据更新对象INDEX正在使用中

我将数据带到我的本地系统并得到了一个不同的例外:

FirebirdSql.Data.FirebirdClient.FbException:违反表格“TYPE”上的FOREIGN KEY约束“INTEG_72”

这确实是外键约束违规。我能够更正更新程序,以包括对数据的更正和正确更新的客户端站点。出于某种原因,我似乎在客户端站点上收到了不正确的初始异常。


注意:我也接受了jachguate在这个帖子中的答案,因为他提供了我认为是我原来问题的正确答案。

2 个答案:

答案 0 :(得分:2)

您可以使用gfix命令行工具关闭数据库以获取对数据库的独占访问权限(您可以从c#程序中调用它,或使用其他工具执行所有维护,例如在服务器)。

来自Database Startup and Shutdown

数据库关闭 如果数据库需要维护工作,您可能希望在某些情况下关闭该数据库。这与停止Firebird服务器不同,因为服务器可能正在运行您不希望影响的其他数据库。 关闭数据库的命令是:
gfix -shut OPTION TIMEOUT database_name
TIMEOUT参数是关闭必须完成的时间(以秒为单位)。如果命令无法在指定时间内完成,则中止关闭。在给定时间内关闭可能无法完成的原因有多种,并且这些原因随关闭模式而变化,如下所述。 OPTION参数是以下之一: * -at [tach] - 阻止新连接。 * -tr [an] - 阻止新交易。 * -f [orce] - 简单地中止所有连接和事务。 关闭数据库时, SYSDBA或数据库所有者仍可以连接以执行维护操作,甚至可以查询和更新数据库表。

从firebird 2.0开始,您还可以在关闭后指定数据库的state

例如

gfix -shut single -force 60 mydatabase.fdb

将在60秒后断开所有活动用户,之后数据库将只允许sysdba或数据库所有者的一个连接。

答案 1 :(得分:-4)

  1. 拔下网线
  2. 执行交易
  3. 插入网络电缆