当前位置: 首页 > 面试题库 >

如何在firebird数据库上获得排他锁以执行架构更改?

萧允晨
2023-03-14
问题内容

更具体地说,我正在为Visual Studio使用firebird 2.1和DDEX Provider,并且正在使用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在此主题中给出的答案,因为他提供了我认为是对原始问题的正确答案。


问题答案:

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

从数据库启动和关闭

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

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

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

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

例如

gfix -shut single -force 60 mydatabase.fdb

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



 类似资料:
  • 问题内容: 我正在重新设计可能多次启动的Java可执行文件,并且希望该过程一次执行一次。在C#中,我将使用具名/系统的Mutex来做到这一点,但这在Java中似乎是不可能的。如何实现此功能? 问题答案: 您可以使用对文件系统上文件的独占访问来实现类似的行为。我认为您所提到的没有类似之处。 例子 Java编程[存档]-以互斥锁打开文件 java.nio.channels.FileLock

  • 问题内容: 嗨,专家,我如何在SQL Server中锁定行,以防止CRUD操作(甚至是SELECT)。是否有可能?可序列化的隔离级别不会阻止SELECT。谢谢 问题答案: 这样就可以了。 编辑 正如其他人所指出的,您不能将行锁定为不被读取 。我知道这样做的唯一方法如下: 并假设在SELECT语句中从未使用过WITH(NOLOCK)(无论如何应避免使用)。 我测试了这一点,并且可以正常工作,尽管TA

  • 问题内容: 如何获得对文件的专有读取访问权?我已经尝试过docs中的文档,但是我仍然能够在记事本中打开文件并进行编辑。我想拒绝任何其他进程具有读写权限,而第一个进程没有明确关闭它。在.NET中,我可以执行以下操作: 我该怎么办? 问题答案: 我终于找到了可以锁定文件的go包。 这是仓库: https : //github.com/juju/fslock 这个包裹完全按照它说的去做 fslock提供

  • 我正在eclipse中使用模拟器。我在模拟器中提取了大约2200条文本消息/data/data/com.android.providers.telephony/databases/mmssms。从emulator中读取db,并在其中看到文本消息 SQLiteDatabase smsDB=SQLiteDatabase.openDatabase("/data/data/com.android.prov

  • 问题内容: 我有一个SQL Server数据库,当在表中插入时,我想通知android应用程序。 例如,当收到订单时,我将其插入到SQL Server数据库中。我还希望用户在我的应用中收到有关订单的通知。该应用程序始终处于打开状态。我使用Web服务与数据库联系。 我不想每10秒钟左右请求一次表格。还有其他办法吗? 问题答案: 您可以使用Google Cloud消息服务,在此处了解如何设置服务器。

  • 问题内容: update 我可以创建我的数据库架构,它会自动添加属性,约束,键等。但是,更新数据库架构又如何呢?如果我从实体中删除了某些属性,hibernate则不会删除它,或者如果我更改了某些约束,则hibernate不会触及已经创建的约束… 那么,有没有一种方法可以使hibernate状态真正更新数据库架构? 谢谢。 问题答案: 我们为自己创建了一个工具,该工具创建了必要的数据库列和表,并将其