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

发布于 2024-10-17 11:20:54 字数 2728 浏览 1 评论 0原文

更具体地说,我正在使用 firebird 2.1 和 Visual Studio 的 DDEX Provider,并且我正在使用 c# 工作。

我遇到了一种情况,我试图将模式更改从 C# 应用到数据库,以“更新”我的数据库。在此过程中,我从 firebird 得到以下异常:

FirebirdSql.Data.FirebirdClient.FbException: 元数据更新对象 INDEX 正在使用中失败

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

示例:

// 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”上的外键约束“INTEG_72”

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


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

To be more specific, I am using firebird 2.1 and the DDEX Provider for visual studio, and I'm working in c#.

I have a situation where I'm trying to apply schema changes to the database from c# in an effort to "update" my database. During this process I get the following exception from firebird :

FirebirdSql.Data.FirebirdClient.FbException: unsuccessful metadata update object INDEX is in use

I've interpreted this as a concurency issue where there is another processess accessing the database at the same time. I do not know this is the cause for certian, but it "seems" the most likely case. I thought it might be related to the deleting and adding of constraints, as in they are not addable because the constraint is not correct, but I am able to run the commands on my local system without error, just not on the client site. At any rate, I currently have a number of commands wrapped into one transaction using isolation level "Serializable", and commit them all at once. As this is an upgrade, the thinking is it can block all other users as needed.

Example:

// 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();

My thought was to try and use the "manual" way of specifying a transaction to perhaps get more exclusive access to the tables, but I can't seem to get it to work as I don't understand what will and will not work together.

Example:

// 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
            );

Anyway, my question is, how do I get exclusive access to the db to perform these updates? I'd almost like to be able to kick everyone off, and do them. Help and suggestions are much appricated!!!


New information:
I was able to bring the data to my local, and now the error is showing as:

FirebirdSql.Data.FirebirdClient.FbException: violation of FOREIGN KEY constraint "INTEG_72" on table "TYPE"

Which is clear, so I'll fix this one and try it on site.


That seems to have fixed it.
So, in summary, I got an exception on a client system say:

FirebirdSql.Data.FirebirdClient.FbException: unsuccessful metadata update object INDEX is in use

I brought the data to my local system and got a different exception:

FirebirdSql.Data.FirebirdClient.FbException: violation of FOREIGN KEY constraint "INTEG_72" on table "TYPE"

Which was indeed a foreign key constraint violation. I was able to correct the update program to include a correction to the data and the client site updated properly. For some reason, I seemed to recieve an incorrect inital exception on the client site.


Note: I also accepted an answer in this thread by jachguate as he provided what I believe is the correct answer to my original question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哑剧 2024-10-24 11:20:54

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

来自数据库启动和关闭

数据库关闭

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

关闭数据库的命令是:

gfix -shut 选项超时数据库名称

TIMEOUT 参数是关闭必须完成的时间(以秒为单位)。如果命令无法在指定时间内完成,则关闭将中止。无法在给定时间内完成关闭的原因有多种,这些原因因关闭模式而异,如下所述。

OPTION 参数是以下之一:

* -at[tach] - 阻止新连接。
* -tr[an] - 阻止新交易。
* -f[orce] - 简单地中止所有连接和事务。

当数据库关闭时,SYSDBA 或数据库所有者仍然可以连接以执行维护操作,甚至查询和更新数据库表。

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

例如,

gfix -shut single -force 60 mydatabase.fdb

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

You can get exclusive access on the database for maintenance by shutting it down using the gfix command line tool (you can call it from your c# program, or perform all the maintenance using another tool, for example a batch script executed on the server).

From Database Startup and Shutdown

Database Shutdown

If there is maintenance work required on a database, you may wish to close down that database under certain circumstances. This is different from stopping the Firebird server as the server may well be running other databases which you do not wish to affect.

The command to close a database is:

gfix -shut OPTION TIMEOUT database_name

The TIMEOUT parameter is the time, in seconds, that the shutdown must complete in. If the command cannot complete in the specified time, the shutdown is aborted. There are various reasons why the shutdown may not complete in the given time and these vary with the mode of the shutdown and are described below.

The OPTION parameter is one of the following:

* -at[tach] - prevents new connections.
* -tr[an] - prevents new transactions.
* -f[orce] - simply aborts all connections and transactions.

When a database is closed, the SYSDBA or the database owner can still connect to perform maintenance operations or even query and update the database tables.

Since firebird 2.0, you can also specify the stateof the database after shutdown:

For example

gfix -shut single -force 60 mydatabase.fdb

will disconnect all active users after 60 seconds, afterwards the database will allow only one connection for sysdba or database owner.

亢潮 2024-10-24 11:20:54
  1. 拔掉网线
  2. 执行交易
  3. 插入网线
  1. Unplug the network cable
  2. Execute the transaction
  3. Plug in the network cable
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文