使用多个连接时无法删除Firebird表

问题描述

我想放下Firebird表。我有3个事务,一个用于重新创建表,一个用于处理表(只需插入一行以保持简单),最后一个用于删除表。 如果所有这些txns是使用单个连接执行的,则这些工作正常。如果我使用其他连接,那么drop命令将失败并显示

在没有等待交易的情况下锁定冲突 元数据更新失败 对象表“ DEMO”正在使用中

private static void test() {
        using var conn1 = new FbConnection(ConnectionString);
        using var conn2 = new FbConnection(ConnectionString);
        using var conn3 = new FbConnection(ConnectionString);
        conn1.open();
        conn2.open();
        conn3.open();
        ExecuteTxn(conn1,cmd => {
            cmd.CommandText = "recreate table demo (id int primary key)";
            cmd.ExecuteNonQuery();
        });
        ExecuteTxn(conn2,cmd => {
            cmd.CommandText = "insert into demo (id) values (1)";
            cmd.ExecuteNonQuery();
        });            
        ExecuteTxn(conn3,cmd => {
            cmd.CommandText = "drop table demo";
            cmd.ExecuteNonQuery();
        });            
    }

    private static void ExecuteTxn(FbConnection conn,Action<FbCommand> todo) {
        using (var txn = conn.BeginTransaction())
        using (var cmd = conn.CreateCommand()) {
            cmd.Transaction = txn;
            todo(cmd);
            txn.Commit();
        }
    }

我意识到将交易选项更改为

txn = conn.BeginTransaction(new FbTransactionoptions { TransactionBehavior = FbTransactionBehavior.Wait }))

似乎有帮助。但是我不确定这是正确的做法还是偶然的事情...

使用Firebird 3.0.6,Firebirdsql.Data.FirebirdClient.dll 7.5.0.0

解决方法

据我了解,问题与Firebird如何缓存某些元数据有关,这可能导致保留存在锁,这将防止对象的删除。另外,有可能-这是一个猜测! -Firebird ADO.net提供程序保留已准备好插入语句的语句句柄,这也将导致保留存在锁。

在Firebird核心开发人员中,在WAIT事务中执行(可选地具有超时)被认为是一种适当的解决方法。

作为参考,请参阅以下票证:

在某些情况下,从Firebird ClassicServer或Firebird SuperClassic切换到Firebird SuperServer也可以防止此问题。

但是,如果您需要更深入的说明,可能值得在firebird-devel邮件列表中提出这个问题。