【发布时间】: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。
标签: c# firebird azure-cloud-services