SSISのトランザクション設定が上手くできない

このQ&Aのポイント
  • SSISのトランザクション設定がうまく動作しない問題についてです。パッケージ全体が成功した場合にのみコミットを行いたいが、うまく動作しないという課題があります。
  • パッケージ全体の[TransactionOption]を[Required]、各タスクの[TransactionOption]を[Supported]、パッケージ全体の[ProtectionLevel]を[DontSaveSensitive]という設定を試しましたが、うまく動作しません。
  • エラーメッセージには、保持されている接続で互換性のないトランザクションコンテキストが指定されたことが原因でエラーが発生していると記載されています。分散トランザクションは動作しているようですが、解決方法がわかりません。
回答を見る
  • ベストアンサー

SSISのトランザクションの設定がうまく出来ない

パッケージ全体が成功すると パッケージ全体をコミットさせる、といった事をしたいのですが、 どうしてもうまく動作してくれません。。 ちなみに、以下の設定を実施しました。 ・パッケージ全体の[TransactionOption]を[Required] ・各タスクの[TransactionOption]を[Supported] ・パッケージ全体の[ProtectionLevel]を[DontSaveSensitive] #もちろん、[TransactionOption]を全て[Supported]にすると、 #問題無く動作します。 以下、エラーメッセージを纏めたものです。 -------------------------------------------------- 開始: XX:XX:XX エラー: 2008-08-XX XX:XX:XX コード: 0xC001A004 説明: 保持されている接続で互換性のないトランザクション コンテキストが指定されました。 この接続は別のトランザクション コンテキストで確立されています。 保持されている接続は 1 つのトランザクション コンテキストのみで使用できます。 エラー終了 -------------------------------------------------- エラー: エラー: 2008-08-XX XX:XX:XX コード: 0xC020801C ソース: フラットファイルよりTestTableへインポート OLE DB 変換先:TestTable [283] 説明: SSIS エラー コード DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER。 エラー コード 0xC001A004 により、接続マネージャ "TestDB" に対する AcquireConnection メソッドの呼び出しが失敗しました。 このエラーの前に、AcquireConnection メソッドの呼び出しが失敗した理由の詳細が記載された エラー メッセージが報告されている可能性があります。 エラー終了 -------------------------------------------------- エラー: 2008-08-XX XX:XX:XX コード: 0xC0047017 ソース: フラットファイルよりTestTableへインポート DTS.Pipeline 説明: コンポーネント "OLE DB 変換先:TestTable" (283) が検証に失敗し、 エラー コード 0xC020801C が返されました。 エラー終了 -------------------------------------------------- このエラーが発生した際に、 「分散トランザクションを中止しています。」と、 パッケージの進行状況に表示されていることから、 分散トランザクション自体は動作しているように見えます。 以上より、 どなたか解決方法をご存知の方、ご教授頂けると幸いです!

質問者が選んだベストアンサー

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.5

>FailPackageOnFailure=False にしてしまうと、 シーケンスコンテナ内で、例えば、フラットファイルが存在しない等のエラーが発生してしまっても、成功の制約に進んでしまうのです、、 (つまり、COMMIT TRANに進んでします) これも普通はありえないですね。無理やり成功にするパラメータはいくつもありますけど、そのどれかが設定されているとしか。 すべてのレベルで、 FailPackageOnFailure=False FailParentOnFailure=False MaximumErrorCount=1 でいいはずです。 >こちらは、SQL実行タスク全てに入れておいた方が良いイメージでしょうか? ROLLBACK TRANだけです。

chic_punk
質問者

お礼

ご回答ありがとうございます! 無事、出来ました! シーケンスコンテナの ForceExecutionResult の値を 変更してしまっておりましたのが原因のようです、、 お騒がせしました。。 しかし、SSISって、設定の関連性が非常に見出しにくいですね、、 jamshid6さまの助けがなければ、どのくらいハマっていたことか、、 改めて、ありがとうございました!!

その他の回答 (4)

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.4

>ちなみに、失敗時、ROLLBACK TRAN には届かずに終了してしまうのですが、こういうものなのでしょうか? 処理自体はちゃんとROLLBACKされているので問題は無いと思うのですが、、 ROLLBACK TRANに届かないということはないと思いますよ。 それはおそらくどこかの処理でFailPackageOnFailure=Trueになっているということでしょう。 エラーになった場合確かにCOMMITしていないTransactionはROLLBACKされますので、なくても実害はないのですが、 ・明示的にROLLBACKした方がフローわかりやすい ・ROLLBACKするが、どこかのテーブルにログは書きたいなどのときは、TransactionModeを終わらせないといけない などの理由でつけることをお勧めします。 なお、SQL実行タスクでDMLでエラーが生じたときは、そのエラー自体でROLLBACKが発生してしまいますので、 IF (@@TRANCOUNT>0) ROLLBACK TRAN と書いておくことをお勧めします。

chic_punk
質問者

補足

ご回答ありがとうございます。 FailPackageOnFailure=False にしてしまうと、 シーケンスコンテナ内で、例えば、フラットファイルが存在しない等のエラーが発生してしまっても、成功の制約に進んでしまうのです、、 (つまり、COMMIT TRANに進んでします) これは、ウィザードで作成したものでも同様でした。 > IF (@@TRANCOUNT>0) ROLLBACK TRAN こちらは、SQL実行タスク全てに入れておいた方が良いイメージでしょうか?

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.3

そのイメージで結構です。 SQL Serverはある意味便利なデータベースで、失敗したらDDLだろうがなんだろうがRollBackしてくれます。 余談ですが、データインポート・エクスポートウィザードでSSISパッケージが生成できるのはご存じだと思いますが、これで「多数のテーブル用に最適化する」+「トランザクションで実行する」というチェックを入れて生成すると、まさにそういうパッケージを作ります。

chic_punk
質問者

補足

ありがとうございます!無事、出来ました! ちなみに、失敗時、ROLLBACK TRAN には届かずに終了してしまうのですが、こういうものなのでしょうか? 処理自体はちゃんとROLLBACKされているので問題は無いと思うのですが、、 >「多数のテーブル用に最適化する」+「トランザクションで実行する」というチェックを入れて生成すると、 >まさにそういうパッケージを作ります。 これは、気付いていませんでした。。 こちらも、ありがとうございました!

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

>このケースの場合、やはり、このサイトに記載されているような対応が必要となってくるのでしょうか・・? http://www.logistech.co.jp/techtips/msdtc.html そうでしょうね。ただ、私はDTSにせよSSISにせよ、常にローカル(SQL Serverのあるところ)で実行させるようにしているため、その設定は試したことはありません。 なお、こういう場合の別のアプローチを紹介しておきます。 1) 接続マネージャのRetainSameConnection=Trueに設定する 2) Transactionモードで行いたい処理をシーケンスコンテナに入れる 3) 2)の前提として「BEGIN TRANSACTION」だけ行うSQL実行タスクを置く 4) シーケンスコンテナの成功時の後続に「COMMIT TRANSACTION」を行うSQL実行タスクを置き、失敗時の後続に「ROLLBACK TRANSACTION」を行うSQL実行タスクを置く >最後に、あるサーバ上でそのサーバ上からキックすると、 検証の段階で止まってしまいます。。 これだけでは状況がよくわからないので、なんともコメントできないです。何かエラーメッセージが出るのですか

chic_punk
質問者

補足

jamshid6 さま いつもご回答ありがとうございます。 非常に助かります。 >>このケースの場合、やはり、このサイトに記載されているような対応が必要となってくるのでしょうか・・? >> http://www.logistech.co.jp/techtips/msdtc.html >そうでしょうね。ただ、私はDTSにせよSSISにせよ、常にローカル(SQL Serverのあるところ)で実行させるようにしているため、その設定は試したことはありません。 了解いたしました。 >なお、こういう場合の別のアプローチを紹介しておきます。 >1) 接続マネージャのRetainSameConnection=Trueに設定する >2) Transactionモードで行いたい処理をシーケンスコンテナに入れる >3) 2)の前提として「BEGIN TRANSACTION」だけ行うSQL実行タスクを置く >4) シーケンスコンテナの成功時の後続に「COMMIT TRANSACTION」を行うSQL実行タスクを置き、失敗時の後続に「ROLLBACK TRANSACTION」を行うSQL実行タスクを置く なるほど、、、 イメージとしては、以下でよろしいでしょうか? (Yes, Noだけでもご回答頂ければ幸いです) ----------------------------------------------------------- SQL実行タスク(BEGIN TRANSACTION) ※シーケンスコンテナ外       ↓ ┏━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃シーケンスコンテナ(Transactionモードで行いたい処理) ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━┛   |(成功時)                       |(失敗時)   ↓                             ↓ SQL実行タスク(COMMIT TRANSACTION)     SQL実行タスク(ROLLBACK TRANSACTION) ※シーケンスコンテナ外                 ※シーケンスコンテナ外 ----------------------------------------------------------- >>最後に、あるサーバ上でそのサーバ上からキックすると、 >>検証の段階で止まってしまいます。。 >これだけでは状況がよくわからないので、なんともコメントできないです。何かエラーメッセージが出るのですか そうですよね、、 こちら、新たにログ等の情報が取得出来ましたら、またご教授頂きたく存じます。 (ちなみに、エラーメッセージは何も出ず、処理が凍りついたように全く動かなくなってしまいます。)

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

該当の接続のRetainSameConnection=Trueにしていますか? SSISでは、すでに確立済の接続がある場合、Transactionモードを指定できないので、TransactionOptionをRequiredにしたいときは、RetailSameConnection=Falseにしてください。

chic_punk
質問者

お礼

-------------------------------------------------- おかげさまでバッチリ実行できました! ただ、自身のローカル上だけでローカルに対して 実行すると問題なく動作するのですが、 ローカルから別サーバに対して実行しようとすると、以下のエラーが出てしまいます。 -------------------------------------------------- [接続マネージャ "TextMiningDB"] エラー : エラー 0x8004D025 "パートナー トランザクション マネージャにより、 リモート トランザクションまたはネットワーク トランザクションのサポートが無効にされました。" により、 SSIS ランタイムは OLE DB 接続を分散トランザクションに参加させることができませんでした。 -------------------------------------------------- このケースの場合、やはり、このサイトに記載されているような対応が必要となってくるのでしょうか・・? http://www.logistech.co.jp/techtips/msdtc.html ちなみに、シーケンスコンテナで括っても、 結局は Required がないとだめなんですね。。 最後に、あるサーバ上でそのサーバ上からキックすると、 検証の段階で止まってしまいます。。 これは、何か考えられる原因はありますでしょうか・・?

chic_punk
質問者

補足

たびたびのご回答ありがとうございます。 (神ですか?) 早速試してみます!

関連するQ&A

  • SSIS(SP1)で発生するエラーについて。

    皆様、お世話になります。 まず、初めに環境を晒します。 ・OS WindowsServer2003 SP1 ・DB SQLServer2005 SP1 SSISを使用しフラットファイルをDBに収めるという処理を行っております。 そのSSISの中で緩やかなディメンションを使用し追加更新を行っておりますがエラーが発生します。(検証エラー) 以下が、検証エラー内容です。 [挿入先 [1840]] エラー : OLE DB エラーが発生しました。エラー コード: 0x80040E37。 OLE DB レコードを使用できます。ソース: "Microsoft SQL Native Client" Hresult: 0x80040E37 説明: "分散トランザクションが完了しました。このセッションを新規トランザクションまたは NULL トランザクションのいずれかに参加させます。"。 マイコン-管理にて分散トランザクションの設定は行っております。 といってもサービス起動の確認をしただけですが・・・ 以上の処理をSQLServer2005 "SP2"で動かしたところ正常に動作します。 SP1で使えないということはバグと認識したいのですが確かなソースが ありません。SP1でもSSISを実装できるってことはバグとも考えにくいし混乱している状態です。 この情報に関する事を知っている方、是非よろしくお願い致します。

  • SQLServer 分散トランザクションについて

    現在サーババージョンアップに伴うストアドの動作検証を行っています。 内容としては2000で動作していたものを2008R2に移行するだけです。 そこでひとつ問題が発生して作業がとまってしまいましたので、 お力を借りたく、質問させていただきます。 環境としては、クライアントはACCESSプログラム、DBはSQLServerとなっています。 ストアドの実行で下記のように記載していたプログラムが動作しなくなりました。 Set adoCN = New ADODB.Connection adoCN.Open CurrentProject.Connection adoCN.BeginTrans adoCN.Execute "exec dbo.実行ストアド" 'エラー判定 adoCN.CommitTrans 上記エラー判定で「リンク サーバー "(null)" の OLE DB プロバイダー "SQLNCLI10" から、 メッセージ "アクティブなトランザクションがありません。" が返されました。」 となってしまいます。 また、このストアド内では「SET XACT_ABORT ON ~ SET XACT_ABORT OFF」 としてあります。 ちなみに、上記「adoCN.BeginTrans」、「adoCN.CommitTrans」をコメントすると、 正常に動作しました。 「SET XACT_ABORT ON」としているので「adoCN.BeginTrans」はなくてもいいと思うのですが、 明確に『不要である』としている文献等、見つからなかったため、迷っています。 サーバはバージョンアップに伴い、分散トランザクションを使用するようになっていますが、 この変更が影響しているのかどうか、まったく別の原因なのか、わからない状態です。 うまく伝わっているか心配ですが、どうぞ宜しくお願い致します。

  • SQLサーバへのデータセットについて

    SQLサーバ2008へのデータ変換ツール(DTS)を使用してのデータセットを行っているのですが、 うまくいきません。ログインしてDTS起動を指定してるバッチファイルを起動したら正常に動作する のですが、そのバッチファイルを別サーバよりリモートコマンドにて起動するとエラーになります。 ↓ エラー内容 SSIS エラー コード DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER。エラー コード 0x80004005 により、接続マネージャ "DestinationConnectionOLEDB" に対する AcquireConnection メソッドの呼び出しが失敗しました。 ↑ エラー内容 どなたかご存じの方、教えて頂けませんか? よろしくお願いします。

  • エラーについて(更新)

    Txtファイルには 1,A ~ 10,A のデータが入ってます。 データベースはmysqlで mysqlにはフィールドは ID NAMEで 1  1 ~ 9  1 のデータ9つが入ってます。 Txtファイルの10番目のデータを更新させると データベースにそれに対応したコードがないため エラーが出るはずなのですが、 エラーの形が次のようになります。 データが登録されました。データが登録されました。アクティブなトランザクションがありません。 アクティブなトランザクションがありません。 アクティブなトランザクションがありません。 アクティブなトランザクションがありません。 アクティブなトランザクションがありません。 アクティブなトランザクションがありません。 アクティブなトランザクションがありません。 アクティブなトランザクションがありません 何故なのでしょうか? 自分ではtxtファイルの10番目のデータを更新するときにだけエラーがでると考えているのですがそのように 動作してくれません。何故そのように動作しないのでしょうか?また、エラーがでているにもかかわらず 更新処理は全て正常に動作しています。 コードについても載せたいのですが 文字数制限で載せることができませんので 回答していただいた後に、補足で載せさせて頂きたい と思います。

  • OracleからSQLServer 2008へのデータのインポート

    Oracleからデータを取得し、SQL Server 2008へデータをインポートした際に、下記のエラーが発生します。これはどういう状態でしょうか? データ長がオーバーしているという事はないはずですので、何か別の問題がおきているのかと思われますが。。 どなたか是非、ご教授お願い致します。 メッセージ エラー 0xc02020c5: データ フロー タスク 1: 列 "xxxxxxxxx" (41) を列 "xxxxxxxxx" (485) に変換しているときに、データ変換に失敗しました。この変換により、状態値 4 と状態を示すテキスト "テキストが切り捨てられたか、または対象になるコード ページで 1 つ以上の文字が一致しませんでした。" が返されました。 (SQL Server インポートおよびエクスポート ウィザード) エラー 0xc020902a: データ フロー タスク 1: "出力列 "xxxxxxxxx" (485)" が切り捨ての発生により失敗しました。"出力列 "xxxxxxxxx" (485)" の切り捨て行の処理により、切り捨てによる失敗が示されます。ここに示されたコンポーネントのオブジェクトで切り捨てエラーが発生しました。 (SQL Server インポートおよびエクスポート ウィザード) エラー 0xc0047022: データ フロー タスク 1: SSIS エラー コード DTS_E_PROCESSINPUTFAILED。入力 "データ変換の入力" (446) の処理中に、コンポーネント "データ変換 0 - 0" (445) の ProcessInput メソッドがエラー コード 0xC020902A で失敗しました。このコンポーネントは、ProcessInput メソッドからエラーを返しました。このエラーはコンポーネントに固有のものですが、致命的なエラーであるため、データ フロー タスクの実行は停止されます。このエラーの前に、エラーの詳細が記載されたエラー メッセージが報告されている可能性があります。 (SQL Server インポートおよびエクスポート ウィザード) エラー 0xc02020c4: データ フロー タスク 1: エラー コード 0xC0047020 により、データ フロー タスク バッファに行を追加できませんでした。 (SQL Server インポートおよびエクスポート ウィザード) エラー 0xc0047038: データ フロー タスク 1: SSIS エラー コード DTS_E_PRIMEOUTPUTFAILED。コンポーネント "変換元 - xxxxxxxxx" (1) の PrimeOutput メソッドからエラー コード 0xC02020C4 が返されました。パイプライン エンジンが PrimeOutput() を呼び出したときに、このコンポーネントからエラー コードが返されました。このエラー コードの意味はコンポーネントで定義されていますが、これは致命的なエラーであるため、パイプラインの実行は停止されました。このエラーの前に、エラーの詳細が記載されたエラー メッセージが報告されている可能性があります。 (SQL Server インポートおよびエクスポート ウィザード)

  • SSISのOLE DBソースでSQLSeverに接続時のパスワード保存について

    宜しくお願い致します。 SSISのOLE DBソースでSQLSeverに接続する時、設定画面にて、「SQL Server認証を使用する」を選択し、ユーザー名、パスワードを入力し、パスワードの保存にチェックを入れ保存し、デバックを実行するとエラーになってしまいます。  パッケージファイルを開き、パスワードを直接記入し、実行するとうまくいくのですが、パッケージファイルを直接変更する以外の方法は、ないのでしょうか? ご教示頂けましたら大変助かります。 宜しくお願い致します。

  • vb.net トランザクション処理について

    VB2005、SQLServer2005環境です。 VB.Netのトランザクション処理でエラーが発生します。 エラー内容の意味すらわかりません。 どなたかご教授お願いします。 *エラー内容 "System.InvalidOperationException: ExecuteReader は、コマンドに割り当てられた接続が保留状態である ローカルのトランザクションにあるとき、トランザクション オブジェクトを持つコマンドが必要です。 コマンドの Transaction プロパティがまだ初期化されていません。 Private Sub BTN_更新_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN_更新.Click Dim strsql As String Dim Tran As SqlClient.SqlTransaction = Nothing '---DB接続 Call DBConnect() Try '---SQL文作成 strsql = "SELECT * FROM Aテーブル" '---SQL文を作成して実行する Dim comm As SqlCommand = New SqlCommand(strsql, Con) '---データアダプタの作成 Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm) '---データセットへの読み込み Dim ds As DataSet = New DataSet() dataadapter.Fill(ds, "Aテーブル") Dim dt As New DataTable dt = ds.Tables("Aテーブル") '---主キーの設定 dt.PrimaryKey = New DataColumn() {dt.Columns("Aテーブル")} '---データの更新 Dim targetRow As DataRow targetRow = dt.NewRow() targetRow = dt.Rows.Find(TXT_コード.Text) targetRow("コード") = TXT_コード.Text targetRow("氏名") = TXT_氏名.Text '---コマンド自動作成 Dim cb As SqlCommandBuilder = New SqlCommandBuilder(dataadapter) '---トランザクション開始 Tran = Con.BeginTransaction() '---データベースの更新 dataadapter.Update(ds, "社員テーブル")     <<<エラーになります。 '---トランザクション完了 Tran.Commit() Catch oExcept As Exception '---ロールバック Tran.Rollback() '例外が発生した時の処理 MessageBox.Show(oExcept.ToString, "例外発生") Finally '---DB切断 Call Disconnect() End Try

  • SQLServerへodbc接続トランザクション

    PHP 5.6.3 SQLServer 2014 IIS 8.5 Web上からPHPへPOSTし、SQLServerへODBC関数(http://php.net/manual/ja/ref.uodbc.php)を使用して接続しています。 その際「odbc_autocommit」を使用しトランザクションをかけているのですが、 同時にDBへ登録(Insert、Delete)をしたときに競合してしまいました。 そもそも「odbc_autocommit」の挙動として、 (1)A端末からDBへ接続 (2)A端末から「odbc_autocommit」を使用しトランザクション (3)B端末からDBへ接続 (4)B端末から「odbc_autocommit」を使用しトランザクション (5)A端末からTEST_TABLEへInsert (6)B端末からTEST_TABLEへInsert 上記手順の(4)の動作の際に、A端末の操作が終わるまでBは待たされるorエラーでかえると想定していたのですが・・・ ----------------------------------------------------------- $serverCon = odbc_connect($serverName,$userName,$password); if($serverCon === false){ $strMsg = ERRMSG_DBCONNECT; writeLog($strMsg, DEBUG_LOG); jumpSystemErrPage(); exit(); } $boCon = true; // 自動コミットをさせないようにする $a = odbc_autocommit($serverCon,false); if($a === false){ $strMsg = ERRMSG_DBCONNECT; writeLog($strMsg, DEBUG_LOG); $aaaa = odbc_errormsg($serverCon); writeLog($aaaa, DEBUG_LOG); jumpSystemErrPage(); exit(); } ----------------------------------------------------------- 確認方法として A端末にてデバッグ状態から上記ソース上の if($a === false){ の行でブレイクしてる最中に B端末から普通に実行した際に $aがfalseのルートに通らずそのまま次の処理へ行ってしまいました。 PHPのODBC接続で更新中にトランザクション(ロック)をかけるのはできないのでしょうか? それとも自分のやり方が間違っているのでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • MFC ADOでSQL Serverに接続するには

    初心者の初めての質問です。ご教授よろしくお願いします。 開発環境は Microsoft Visual Studio Term System 2008 OS XP SP3 Microsoft SQL Server 2005 です。 VC++ MFC、SQL Serverでプログラムを組んでいるのですが、 今DB接続に困っています。 「Provider=MSDASQL;DSN=DB名;UID=ID;PWD=PassWord」の文字列を使ってDBとの接続ができますが、 一回目のトランザクションが失敗します。 エラー内容は 「 DbConnection::Transaction COM Error:80004005 Source:Microsoft OLE DB Provider for ODBC Drivers エラーを特定できません 」 です。 解決方法を教えて頂ければ幸いです。

  • postgreSQL を OleDB 接続

    postgreSQL が Linux:CentOS上にあり OS:Windows Vista 開発環境 : VisualStudio 2005 言語 : C# ソフトを開発しております、接続は正常に終了(OleDbConnectionのOpen())するのですが 読み込みコマンドが失敗します(OleDbDataAdapterのFill) "'PostgreSQL OLE DB Provider' は失敗しましたが、エラー メッセージはありません。結果コードは -2147221163(0x80040155) です。" 解決方法をご存知のかたいらっしゃいますでしょうか?