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

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

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

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”

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


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

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

从数据库启动和关闭

数据库关闭如果数据库需要维护工作,您可能希望在某些情况下关闭该数据库。 这与停止Firebird服务器不同,因为服务器可能正在运行您不希望影响的其他数据库。 关闭数据库的命令是:

  gfix -shut OPTION TIMEOUT database_name 

TIMEOUT参数是关闭必须完成的时间(以秒为单位)。如果命令无法在指定时间内完成,则中止关闭。 在给定时间内关闭可能无法完成的原因有多种,并且这些原因随关闭模式而变化,如下所述。 OPTION参数是以下之一:* -at [tach] – 阻止新连接。 * -tr [an] – 阻止新交易。 * -f [orce] – 简单地中止所有连接和事务。 关闭数据库时, SYSDBA或数据库所有者仍可以连接以执行维护操作 ,甚至可以查询和更新数据库表。

从firebird 2.0开始,您还可以在关机后指定数据库的状态:

例如

 gfix -shut single -force 60 mydatabase.fdb 

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

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