[seasar-dotnet:1760] メソッド単位にかけたトランザクションがクラス全体にかかる

kircheis [E-MAIL ADDRESS DELETED]
2010年 7月 6日 (火) 00:34:07 JST


はじめまして、ナガイシと申します。

今、以下の環境でQuill + S2Dao.Netでスマートクライアント開発を
行うべく、サンプルを作成しています。

開発環境
Windows XP SP3
VisualBasic 2008 (.Net Framework3.5)
S2Container.Net 1.3.17 (Quill)
Oracle11.2.0.1
ODP.NET 2.112.1.0

サンプル構成
(1)Windows Form (SampleFormクラス)
 ↓
(2)ASP.NET XML Service (SampleWebServiceクラス)
 ↓
(3)BusinessLogic (SampleBusinessLogicImplクラス(←ISampleBusinessLogicイ
ンターフェース)) ※トランザクション属性
 ↓
(4)DAO Interface (IM_TESTdaoインターフェース)

BusinessLogicにDataInsert、DataUpdate、DataDeleteメソッドを作成し
各メソッドにTransaction属性をつけてメソッド単位のトランザクション処理を
行うべく作成を行いました。
各メソッドのコミット、ロールバックは正常に行われるのですが
例えば、DataInsertメソッドにのみTransaction属性を付加しても
Transaction属性をつけていないDataUpdate、DataDeleteメソッドで
コミット、ロールバックが発生してしまいます。
(クラス全体にTransaction属性はなく、DaoにもTransaction属性はありません)

DataInsertメソッドの流れの概略は以下の通りです。
(1)より(2).DataInsertメソッドを呼出
 ↓
(2).DataInsertメソッドより(3)のDataInsertメソッドを呼出
 ↓
(3).DataInsertメソッドは(4)のInsertDataメソッドを呼出


下記ソースの
<<BusinessLogic>>
 →※クラス
  →Public Class SampleBusinessLogicImpl
   →<Transaction()>
Public Overridable Function DataInsert(ByVal entity As M_TESTentity) 〜
がTransaction属性の部分です。


今回がスマートクライアントもSeasar.Netも初めてで
色々調べてみましたが、トランザクションがかからない現象は
よく見かけるのですが、トランザクションの範囲が想定以上に
なる現象は発見できませんでした。

下記にソースを記載しております。
ソースが長く申し訳ありませんが
何かお気づきの事があればご助言頂きたいと考えております。
よろしくお願いいたします。




<<Windows Form>>
Public Class SampleForm

Private Sub btnExec_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnExec.Click

Dim _SampleWebService As New SampleWebService.SampleWebService
Dim _entity As New SampleWebService.M_TESTentity
Dim _entityList() As SampleWebService.M_TESTentity

With _entity
.Seqid = txtID.Text
.Name = txtNAME.Text
.Birth = CDate(dtpBirth.Value)
.Biko = txtBIKO.Text
End With

Select Case True
Case rdoInsert.Checked
If _SampleWebService.DataInsert(_entity) Then
MessageBox.Show("正常")
Else
MessageBox.Show("異常")
End If
Case rdoUpdate.Checked
If _SampleWebService.DataUpdate(_entity) Then
MessageBox.Show("正常")
Else
MessageBox.Show("異常")
End If
Case rdoDelete.Checked
If _SampleWebService.DataDelete(_entity) Then
MessageBox.Show("正常")
Else
MessageBox.Show("異常")
End If
End Select
End Sub

<<Web Service>>
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)>
_
<ToolboxItem(False)> _
Public Class SampleWebService
Inherits System.Web.Services.WebService

Protected injector As QuillInjector = QuillInjector.GetInstance
Protected SampleClass As ISampleBusinessLogic

Public Sub New()
injector.Inject(Me)
End Sub

<WebMethod()> _
Public Function DataInsert(ByVal entity As M_TESTentity) As Boolean
Return SampleClass.DataInsert(entity)
End Function

<WebMethod()> _
Public Function DataUpdate(ByVal entity As M_TESTentity) As Boolean
Return SampleClass.DataUpdate(entity)
End Function

<WebMethod()> _
Public Function DataDelete(ByVal entity As M_TESTentity) As Boolean
Return SampleClass.DataDelete(entity)
End Function
End Class


<<Web.config>>
<quill>
<dataSources>
<dataSource name="ds">
<provider>ODP</provider>
<connectionString>"Data Source=ORA_SAMPLE;User
ID=sampleuser;Password=samplepwd"</connectionString>
<class>Seasar.Extension.Tx.Impl.TxDataSource</class>
</dataSource>
</dataSources>

<assemblys>
<assembly>Seasar</assembly>
<assembly>Seasar.Dao</assembly>
<!-- Oracle Data Provider for .NET を使用する場合に必要です。 -->
<assembly>Oracle.DataAccess, version=2.112.1.0, Culture=neutral,
PublicKeyToken=89b483f429c47342</assembly>
<!--<assembly>SampleBusinessLogic</assembly>-->
</assemblys>
</quill>





<<BusinessLogic>>
※インターフェース
<Implementation(GetType(SampleBusinessLogicImpl))> _
Public Interface ISampleBusinessLogic
Function DataInsert(ByVal entity As M_TESTentity) As Boolean
Function DataUpdate(ByVal entity As M_TESTentity) As Boolean
Function DataDelete(ByVal entity As M_TESTentity) As Boolean
End Interface

※クラス
Public Class SampleBusinessLogicImpl
Implements ISampleBusinessLogic

Protected daoObject As IM_TESTdao
<Transaction()>
Public Overridable Function DataInsert(ByVal entity As M_TESTentity) As
Boolean Implements ISampleBusinessLogic.DataInsert
Dim intResult As Integer
intResult = daoObject.InsertData(entity)
Return True
End Function

Public Function DataUpdate(ByVal entity As M_TESTentity) As Boolean
Implements ISampleBusinessLogic.DataUpdate
Dim intResult As Integer
intResult = daoObject.UpdateData(entity)
Return True
End Function

Public Function DataDelete(ByVal entity As M_TESTentity) As Boolean
Implements ISampleBusinessLogic.DataDelete
Dim intResult As Integer
intResult = daoObject.DeleteData(entity)
Return True
End Function
End Class


<<Dao Interface>>
※インターフェース
<Implementation()> _
<S2Dao()> _
<Bean(GetType(M_TESTentity))> _
Public Interface IM_TESTdao
Inherits AbstractBaseDao

Function InsertData(ByVal data As M_TESTentity) As Integer
Function UpdateData(ByVal data As M_TESTentity) As Integer
Function DeleteData(ByVal data As M_TESTentity) As Integer
End Interface

※エンティティクラス
<Table("M_TEST")> _
Public Class M_TESTentity
Inherits AbstractBaseEntity

Private _seqid As String
Private _name As String
Private _birth As Nullable(Of Date)
Private _biko As String

Public Sub New()
_seqid = ""
_name = ""
_biko = ""
End Sub

<Column("SEQID")> _
Public Property Seqid() As String
Get
Return _seqid.PadRight(5, " ") 'PrimaryKeyがChar型の場合、桁数に合わせて
空白を付加しないと自動作成SQLと連動できない
End Get
Set(ByVal value As String)
_seqid = value
End Set
End Property

<Column("NAME")> _
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property

<Column("BIRTH")> _
Public Property Birth() As Date
Get
Return _birth
End Get
Set(ByVal value As Date)
_birth = value
End Set
End Property

<Column("BIKO")> _
Public Property Biko() As String
Get
Return _biko
End Get
Set(ByVal value As String)
_biko = value
End Set
End Property

End Class



seasar-dotnet メーリングリストの案内