从连接 Firebird 读取数据时出错

Posted

技术标签:

【中文标题】从连接 Firebird 读取数据时出错【英文标题】:Error reading data from the connection Firebird 【发布时间】:2015-09-23 09:02:07 【问题描述】:

我们正在努力将数据从不同的源系统(Firebird、Oracle、SQL Server)迁移到一个目标系统(SQL Server)。

我们从 Firebird 连接中收到从连接中读取数据时出错异常。

我们正在使用的代码

用于创建 SourceSystem 对象的静态 DbFactory 类

public static class DbFactory

    public static DbManager CreateDb(SourceDbType type)
    
        switch (type)
        
            case SourceDbType.Sql:
                return new SqlDbManager();
            case SourceDbType.FireBird:
                return new FireBirdDbManager();
        
        return null;
    


public enum SourceDbType

    Sql, FireBird

基础 DbManager 类

public abstract class DbManager

    private DbConnection m_DbConnection;
    public virtual DbConnection DbConnection
    
        get
        
            if (m_DbConnection == null)
            
                m_DbConnection = new SqlConnection();
            
            return m_DbConnection;
        
        set
        
            this.m_DbConnection = value;
        
    



    public virtual void SetConnectionString(Migration migration, DataTable dtConnectionDetails = null)
    
        try
        
            DbConnection.ConnectionString = string.Format("Server=0;Database=1;User ID=2;Password=3;",
           migration.NetworkPartnerData.Server,
           migration.NetworkPartnerData.Database,
           migration.NetworkPartnerData.User,
          AESEncryptionDecryptionUtility.DecodeBase64(migration.NetworkPartnerData.Password));
        
        catch
        

            throw;
        


    

    public virtual void SetConnectionString(string connectionString)
    
        try
        
            DbConnection.ConnectionString = connectionString;
        
        catch
        

            throw;
        


    

    public virtual DataTable ExecuteDataTable(string ConnectionString, string queryText)
    
        throw new NotImplementedException();
    

FireBirdDbManager 类继承自 DbManager

 public class FireBirdDbManager : DbManager

    private FbConnection fbconnection;
    public override DbConnection DbConnection
    
        get
        
            if (fbconnection == null)
            
                fbconnection = new FbConnection();
            
            return fbconnection;
        
        set
        
            this.fbconnection = value as FbConnection;
        
    

    public override void SetConnectionString(Migration migration, DataTable connectionDetails)
    

        this.DbConnection.ConnectionString = string.Format("Server=0;Database=1;Port=3050;User ID=2;Password=3;Pooling=true;MinPoolSize=0;MaxPoolSize=50;",
            migration.NetworkPartnerData.Server,
            migration.NetworkPartnerData.Database + BuildDatabaseName(Convert.ToString(connectionDetails.Rows[0]["CL_NBR"])) + ApplicationConstants.FIREBIRD_DBFILE_EXTENSION,
            migration.NetworkPartnerData.User,
           iMigrationTool.Common.AESEncryptionDecryptionUtility.DecodeBase64(migration.NetworkPartnerData.Password));
    
    public override DataTable ExecuteDataTable(string ConnectionString, string queryText)
    
        using (var connection = new FbConnection(ConnectionString))
        
            try
            


                DataTable dt = new DataTable();
                connection.Open();
                using (FbTransaction readTransaction = connection.BeginTransaction(IsolationLevel.ReadCommitted))
                
                    FbCommand readCommand = new FbCommand();
                    try
                    
                        readCommand.CommandText = queryText;
                        readCommand.Connection = connection;
                        readCommand.Transaction = readTransaction;
                        FbDataAdapter da = new FbDataAdapter(readCommand);
                        da.SelectCommand.CommandType = CommandType.Text;
                        da.Fill(dt);

                        readTransaction.Commit();
                    
                    catch
                    
                        readTransaction.Rollback();
                        throw;
                    
                    finally
                    
                        readTransaction.Dispose();
                        if (connection.State == ConnectionState.Open)
                        
                            connection.Close();
                        
                        connection.Dispose();
                    
                    return dt;
                
            
            catch (Exception ex)
            
                int errorCode = ex.HResult;
                Logger.LogApplicationException(ex, null, "ERRORCODE:" + errorCode + "ConnectionString:" + ConnectionString, "MigrationWorker");
                throw ex;
            
        
    

异常图像

在运行 3 到 4 次迁移后,我们遇到了异常。如果我再次重启服务,我们可以运行 3 到 4 次迁移。

我们用来调用各个源系统的代码:

我们对 Firebird 数据库系统非常陌生,无法解决问题。附带说明一下,我们使用的是 Visual Studio 2012,Azure 云服务

【问题讨论】:

“从连接读取数据时出错”通常意味着连接被意外关闭或产生低级 IO 错误。您使用的是哪个 Firebird 版本,以及哪个数据库连接库和版本?也可以尝试禁用连接池。 @MarkRotteveel 感谢您的意见。我需要与 Offshore 团队核实,因为我们正在使用 FlameRobin Database Admin 连接到 Firebird 服务器。我们正在使用库 DLL:FirebirdSql.Data.FirebirdClient 和版本:4.8.0.0,删除了连接池和正在进行的测试 @MarkRotteveel 还是同样的问题没有运气:( 任何其他建议 我能给你的唯一建议是升级到更新的 Firebird 版本 (2.5.4)。 为了扩展我之前的评论,看起来服务器进程(对于经典来说是每个连接)崩溃了。这可能与使用带有错误的 UDF 有关,但也可能是由 Firebird 本身的错误引起的。自 2.0.7 以来,已经有相当多的 Firebird 版本修复了服务器崩溃的错误。您可能还想检查服务器的 firebird.log。 【参考方案1】:

在通过 ADO.NET 数据提供程序(版本 4.7.0)执行查询期间,通过任务管理器终止 Firebird 任务,我们能够重现 Firebird 2.1.3.18185 的问题。之后,我们总是收到以下异常:

System.Data.Entity.Core.EntityCommandExecutionException: An error occurred 
while executing the command definition. See the inner exception for details. 
    ---> FirebirdSql.Data.FirebirdClient.FbException: Error reading data from 
    the connection.
    ---> FirebirdSql.Data.Common.IscException: Error reading 
    data from the connection. at 
    FirebirdSql.Data.Client.Managed.Version10.GdsTransaction.BeginTransaction(Transa
    ctionParameterBuffer tpb) in c: Users Jiri Documents devel NETProvider 
    working NETProvider src FirebirdSql.Data.FirebirdClient Client Managed 
    Version10 GdsTransaction.cs:line 162 at 
    FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.BeginTransaction(Transacti
    onParameterBuffer tpb) in c: Users Jiri Documents devel NETProvider working 
    NETProvider src FirebirdSql.Data.FirebirdClient Client Managed Version10 
    GdsDatabase.cs:line 571 at 
    FirebirdSql.Data.FirebirdClient.FbTransaction.BeginTransaction() in c: Users 
    Jiri Documents devel NETProvider working NETProvider src 
    FirebirdSql.Data.FirebirdClient FirebirdClient FbTransaction.cs:line 363 
— End of inner exception stack trace —

在我们的例子中,问题已通过禁用连接池得到解决和验证(连接字符串:'...;Pooling=false')。对我们来说有趣的是,根据 [1],这是在使用连接池时的预期行为,其中连接已在多个请求之间断开。

我希望这个答案对其他人有所帮助。在我们的案例中,此解决方案也适用于当前的 ADO.NET 5.0.5。

最好的问候, 托马斯

[1]http://tracker.firebirdsql.org/browse/DNET-585?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel

【讨论】:

禁用连接池 (connection-string: '...;Pooling=false') 成功了。谢谢你:) 我也遇到了这个问题。很遗憾,在那之后我们在 ADO.net 组件的 5.12 版中没有解决这个问题!! 警告: 取决于应用程序的体系结构,但禁用池并不是每个应用程序的好选择,因为每次打开新连接时都会花费大量时间。更好的解决方案是设置connection.ConnectionLifeTime = 60秒(左右),让池管理器管理旧连接。【参考方案2】:

执行查询长度> 最大查询长度

时出现此错误

在 FireBird 4.x 中,我从连接中读取数据时出错 更新到 6.6 后,我收到新错误“335544721:无法完成对主机的网络请求...”

已通过将查询拆分为更少的查询来修复

(使用 UTF-8 时默认为 8191 个字符)

【讨论】:

以上是关于从连接 Firebird 读取数据时出错的主要内容,如果未能解决你的问题,请参考以下文章

读取边带数据包时安装 HomeBrew 意外断开连接时出错

从 MySQL 表 1064 读取数据时出错 (42000)

从串口读取数据时出错

从 sparlyr tibble 对象读取数据时访问列时出错

Selenium C#从Excel读取数据以进行数据驱动测试时出错

Presto 查询错误:读取尾部时出错