- PR -

2層コミットについて

1
投稿者投稿内容
Tama
会議室デビュー日: 2005/02/02
投稿数: 19
お住まい・勤務地: 群馬県
投稿日時: 2006-08-30 15:06
お世話になります。

[開発環境]
VB.Net 2003
SQL Server 2005
Windows 2000


これまで、リンクサーバーを利用して処理を行っておりましたが、処理速度の問題があり
それぞれのDBに別々に接続しようと考えております。

そこで、DBが別々でも一括でトランザクションをかけられる方法があるということで
以下のように処理を組んでみました。
しかしながら、ロールバックが行えず、常にDBへ情報が書き込まれてしまいます。

どこに問題があるのかご指導頂ければ幸甚に存じます。


以下に処理を記載させて頂きます。
本クラスの関数は、別クラスからNew宣言して呼んでいます。

' clsTransaction
Imports System.EnterpriseServices
Imports System
Imports System.IO

' トランザクション属性は、クラス トランザクションを有効にします。クラスによってオブジェクトのトランザクションの種類を
' 次のいずれかに設定できます :
'
' Required
' Required New
' Supported
' Not Supported
' Disabled

<Transaction(TransactionOption.Required)> _
Public Class clsTransaction
Inherits ServicedComponent


'--------------------------------------------------------------------------
' モジュール変数
'--------------------------------------------------------------------------
Private m_objDB As clsDB '
Private m_objDB2 As clsDB '

''' -----------------------------------------------------------------------------
''' メイン処理
''' -----------------------------------------------------------------------------
<AutoComplete()> Public Sub Start(ByVal _objFile As IO.FileInfo, ByVal _strSavePath As String)

'--------------------------------------------------------
' 変数宣言
'--------------------------------------------------------
Dim i As Integer ' カウンタ
Dim intRet As Integer ' 各関数の戻り値


Try
' 【DB】接続 (dbオブジェクト宣言 & プロパティセット
m_objDB = New clsDB(strDBConn)
m_objDB2 = New clsDB(strDBConn2)

' 【DB】開く
m_objDB.Open()
m_objDB2.Open()

' datファイルから情報を取得
GetDatData(tRecord, _objFile.FullName)

'-----------------------------------------------------------
' 登録処理
'-----------------------------------------------------------
For i = 0 To UBound(tRecord.tMeisai)
' 登録処理(失敗した場合は、Throwで返す
ExecuteData(tRecord, i)
Next i

' ガベージコレクションの強制実行
System.GC.Collect()
System.GC.WaitForPendingFinalizers()

ContextUtil.SetComplete()

Catch ex As Exception
ContextUtil.SetAbort()
Throw ex

Finally
' 【DB】閉じる
If Not m_objDB Is Nothing Then m_objDB.Close()
If Not m_objDB2 Is Nothing Then m_objDB2.Close()
m_objDB = Nothing
m_objDB2 = Nothing

End Try

End Sub
End Class
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-08-30 21:24
トランザクションをスタートさせるところと、
ロールバックさせているところは?


クラスに必要なんじゃなくて、接続に必要なんじゃない?
Ahf
大ベテラン
会議室デビュー日: 2006/08/16
投稿数: 172
投稿日時: 2006-08-30 22:42
見たところEnterpriseLibraryを利用した分散トランザクションの様子ですが、
MSDNサイトを見ると確かに接続単位でのトランザクション指定は
不要の様子ですね。メソッド開始時点でトランザクションが開始されるという
物のようです。

MSDNのサンプルを参照したところ、
AutoComplete(true)
属性がされていればメソッドにて例外発生時にロールバックが自動的に行われる
という事ですので、属性にtrueまでを追加してみるのはどうでしょうか。

MSDN参考リンク
http://www.microsoft.com/japan/msdn/net/compare/psent.aspx#psent_topic6
がんふぃーるど
ベテラン
会議室デビュー日: 2006/06/05
投稿数: 58
お住まい・勤務地: さいたま
投稿日時: 2006-08-31 03:31
分散トランザクションはほとんど使ったことが無いのですが…

clsDBってデータアクセス用のクラスですよね?
このクラスの中でトランザクションをスタートさせていませんか?
基本的にCOM+トランザクションに参加している場合、
トランザクションを手動で開く必要はありません。(ただしコネクションは自分で開く)

あと、COM+トランザクションは基本的にJITなので、このclsTransactionクラスが
ルートコンポーネントに当たる場合、外部からメソッドを呼び出す度に
サービスコンポーネントのインスタンスは新しくなります。
つまり、Start2みたいなメソッドがあって、外部からStart→Start2の順に
メソッドを呼び出すと、Start2実行時にはm_objDBやm_objDB2はnullになります。

サービスコンポーネントはステートフルな設計にできないので注意して下さい。
1

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