- PR -

DBバックアップ→DBリストア→テーブル内容参照時にException

1
投稿者投稿内容
うっちー
会議室デビュー日: 2007/10/25
投稿数: 2
お住まい・勤務地: 大阪府大阪市
投稿日時: 2007-11-19 14:21
<< 開発環境 >>
C#.NET 2005
SQL Server 2005 Express
Windows XP Professional

DBバックアップ→DBリストアを行った後、DBに再接続しSELECT結果を表示する画面を作成しています。
SELECT発行時に、サーバーに要求を送信しているときに、トランスポート レベルのエラーが発生しました。 (provider: 共有メモリ プロバイダ, error: 0 - パイプの他端にプロセスがありません。のエラーが発生し、対処方法が分からず困っております。
対処方法をご教示賜りたく。
宜しくお願いいたします。

以下、サンプルコードです。
エラー発生場所は、Main→2回目のOutTableInfo内のda.Fill( dt );にて発生しています。(237行目)
DBバックアップ・リストアは、Microsoft.SqlServer.Management.Smoを使用しております。

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Collections;
using System.Threading;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Smo;
using System.IO;

namespace ConsoleApplication1
{
class Program
{
private const string DB_CONNECTION_STR = "Connect Timeout=1;Persist Security Info=false;Integrated Security=false;User ID={0};Password={1};Initial Catalog={2};Data Source={3}";

static SqlConnection connection = null;
static SqlTransaction transaction = null;

const string UserID = "sa";
const string Password = "test";
const string InitialCatalog = "TestDB";
const string DataSource = @".\Test";

static void Main( string[] args )
{
// 接続
if ( DBConnect() )
{
// テストテーブルにレコード追加
InsertTestData( DateTime.Now, "Test" + DateTime.Now.ToString( "yyyyMMddHHmmss" ) );

// テーブル情報表示
OutTableInfo( "Test" );

string backupFile = string.Format( @"d:\Test{0}.bk", DateTime.Now.ToString( "yyyyMMddHHmmss" ) );

// データベースバックアップ
bool retBackup = BackupDatabase( DataSource, InitialCatalog, backupFile );
Console.WriteLine( string.Format( "バックアップ {0}", retBackup ? "OK" : "NG" ) );

// 接続解除
DBDisconnection();

// データベース復元
bool retRestore = RestoreDatabase( DataSource, InitialCatalog, backupFile );
Console.WriteLine( string.Format( "リストア {0}", retRestore ? "OK" : "NG" ) );

// 接続
if ( DBConnect() )
{
// テーブル情報表示
OutTableInfo( "Test" );
}

Console.ReadLine();
}

}
/// <summary>
/// DB接続
/// </summary>
static bool DBConnect()
{
string connectionString = string.Format
(
DB_CONNECTION_STR,
new string[]
{
UserID,
Password,
InitialCatalog,
DataSource
}
);
// 接続
connection = new SqlConnection( connectionString );

for ( int i = 0 ; i < 5 ; i++ )
{
connection.Open();

// 接続できた場合は、ループ終了
if ( connection.State == ConnectionState.Open )
{
Console.WriteLine( "接続OK" );
return true;
}
// 接続できない場合は、リトライ
else
{
Thread.Sleep( 500 );
Console.WriteLine( string.Format("接続NG {0}", i + 1 ) );
}
}
return false;
}
/// <summary>
/// DB切断
/// </summary>
static void DBDisconnection()
{
try
{
connection.Close();
Console.WriteLine( "接続解除OK" );
}
catch
{
Console.WriteLine( "接続解除NG" );
}
}
/// <summary>
/// トランザクション開始処理を行います
/// </summary>
static void BeginTransaction()
{
try
{
transaction = connection.BeginTransaction();
Console.WriteLine( "BeginTransaction OK" );
}
catch
{
Console.WriteLine( "BeginTransaction NG" );
}
}
/// <summary>
/// トランザクションが有効であるか確認します
/// </summary>
static bool IsValidTransaction
{
get
{
if ( transaction == null )
{
return false;
}
if ( transaction.Connection == null )
{
return false;
}
return true;
}
}
/// <summary>
/// コミット
/// </summary>
static void Commit()
{
try
{
transaction.Commit();
transaction.Dispose();

Console.WriteLine( "Commit OK" );
}
catch
{
Console.WriteLine( "Commit NG" );
}
}
/// <summary>
/// ロールバック
/// </summary>
static void Rollback()
{
try
{
transaction.Rollback();
transaction.Dispose();

Console.WriteLine( "Rollback OK" );
}
catch
{
Console.WriteLine( "Rollback NG" );
}
}
/// <summary>
/// Testテーブルにデータを追加します
/// </summary>
/// <param name="dt">日付</param>
/// <param name="value">文字列値</param>
static void InsertTestData( DateTime dt, string value )
{
BeginTransaction();

// date = datetime
// value = varchar(MAX)
string sql = "INSERT TEST( date, value ) VALUES ( @PRM1, @PRM2 )";
SqlParameter[] prm = new SqlParameter[]
{
new SqlParameter( "@PRM1", dt ),
new SqlParameter( "@PRM2", value )
};
try
{
using ( SqlCommand cmd = new SqlCommand( sql, connection ) )
{
cmd.CommandType = CommandType.Text;
if ( IsValidTransaction )
{
cmd.Transaction = transaction;
}
cmd.Parameters.AddRange( prm );
cmd.ExecuteNonQuery();
}
Console.WriteLine( "Insert OK" );
Commit();
}
catch
{
Console.WriteLine( "Insert NG" );
Rollback();
}
}
/// <summary>
/// テーブル情報表示
/// </summary>
/// <param name="tableName">テーブル名</param>
static void OutTableInfo( string tableName )
{
string sql = string.Format( "SELECT * FROM {0}", tableName );

DataTable dt = null;

using ( SqlCommand cmd = new SqlCommand( sql, connection ) )
{

cmd.CommandType = CommandType.Text;

SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;

dt = new DataTable();
da.Fill( dt );
}
// 列名の取得
StringBuilder column = new StringBuilder();
foreach ( DataColumn dc in dt.Columns )
{
if ( column.Length > 0 )
{
column.Append(",");
}
column.Append( dc.ColumnName );
}
column.Append( "\n" );
// 行情報の取得
StringBuilder data = new StringBuilder();
foreach ( DataRow dr in dt.Rows )
{
foreach ( DataColumn dc in dt.Columns )
{
if ( data.Length > 0 )
{
data.Append( "," );
}
data.Append( dr[dc.ColumnName] );
}
data.Append( "\n" );
}
// 列名出力
Console.Write( column.ToString() );
// 行情報出力
Console.Write( data.ToString() );
}

/// <summary>
/// データベースのバックアップを行います
/// </summary>
/// <param name="instanceName">SQL Serverのインスタンス名</param>
/// <param name="databaseName">バックアップを行うデータベース名</param>
/// <param name="backupFilePath">バックアップファイルのパス</param>
/// <returns></returns>
static bool BackupDatabase( string instanceName, string databaseName, string backupFilePath )
{
try
{
Server sv = new Server( instanceName );

Backup bk = new Backup();
bk.Database = databaseName;
bk.Action = BackupActionType.Database;

bk.Devices.Add( new BackupDeviceItem( backupFilePath, DeviceType.File ) );
/// バックアップ実行
bk.SqlBackup( sv );

bk = null;
return true;
}
catch ( Exception e )
{
Console.WriteLine( e.ToString() );
return false;
}
}

/// <summary>
/// データベースの復元を行います
/// </summary>
/// <param name="instanceName">SQL Serverのインスタンス名</param>
/// <param name="databaseName">バックアップを行うデータベース名</param>
/// <param name="restoreFilePath">復元ファイルのパス</param>
/// <returns>true=正常終了/false=異常終了</returns>
static bool RestoreDatabase( string instanceName, string databaseName, string restoreFilePath )
{
try
{
Server sv = new Server( instanceName );

Restore rs = new Restore();
rs.Devices.Clear();
rs.Devices.Add( new BackupDeviceItem( restoreFilePath, DeviceType.File ) );

Database curDatabase = sv.Databases[databaseName];
string curLogicalData = curDatabase.FileGroups[0].Files[0].Name;
string curLogicalDataFile = curDatabase.FileGroups[0].Files[0].FileName;
string curLogicalLog = curDatabase.LogFiles[0].Name;
string curLogicalLogFile = curDatabase.LogFiles[0].FileName;

string relocateDir = Path.GetDirectoryName( restoreFilePath );
// データファイルの割り当て
RelocateFile reloData = new RelocateFile( curLogicalData, curLogicalDataFile );
// ログファイルの割り当て
RelocateFile reloLog = new RelocateFile( curLogicalLog, curLogicalLogFile );
rs.RelocateFiles.Add( reloData );
rs.RelocateFiles.Add( reloLog );

rs.Database = databaseName;
rs.ReplaceDatabase = true;

Console.WriteLine( string.Format( "現在接続数={0}", sv.GetActiveDBConnectionCount( databaseName ) ) );

// データベース削除
sv.KillDatabase( databaseName );

/// 復元実行
rs.SqlRestore( sv );

reloData = null;
reloLog = null;

rs = null;

return true;
}
catch ( Exception e )
{
Console.WriteLine( e.ToString() );
return false;
}
}
}
}
こあら
大ベテラン
会議室デビュー日: 2007/06/26
投稿数: 157
投稿日時: 2007-11-19 16:13
引用:

DBバックアップ→DBリストアを行った後、DBに再接続



最初の接続がプールされてたりしませんか?

http://msdn2.microsoft.com/ja-jp/library/system.data.sqlclient.sqlconnection.clearallpools
うっちー
会議室デビュー日: 2007/10/25
投稿数: 2
お住まい・勤務地: 大阪府大阪市
投稿日時: 2007-11-19 16:44
こあら様 返信有り難う御座います。
SqlConnection.ClearPool( connection );
をconnection.Close() 前に設定することでエラーが発生しなくなりました。
有り難う御座いました。
1

スキルアップ/キャリアアップ(JOB@IT)