[seasar-dotnet:1591] Re: S2Dao.netによるトランザクションの拡張について

西山はじめ [E-MAIL ADDRESS DELETED]
2010年 3月 15日 (月) 14:43:03 JST


西山(hajimeni)です。
横から失礼します。

恐らく原因は、
<Transaction()> _をつけたメソッドが、

Public Overridable Function〜〜〜

になってないからだと思います。

<1>
> AOPは、virtual が付与されたメソッドのみ有効

C# の virtual は、 VB.NETでは Overridable です。
public クラス かつ public virtual(Overridable) がついたメソッドのみAOPの対象となります。

/// うちのチーム内でもよく在る話でしたので。
/// 「トランザクション効かない!」→ 「virtual(Overridable)つけた?」
/// というやりとりが・・・

2010年3月15日14:14 kubo <[E-MAIL ADDRESS DELETED]>:
> 久保(jflute)です。
>
> ログを見ると、確かに一件ごとにトランザクションになっていて、
> あたかも InsertDao にトランザクション属性が
> 付与されているかのような状況に見えますが、
> 「DAOにはTransactionは付与していません」
> とのことなのですね。
>
> <1>
> AOPは、virtualキーワードを付与されたメソッドに
> のみ有効なのですが、VB.NETの文法的にはそれで
> 問題ないか確認してみて下さい。
> (InsertDBのInsertData()メソッドに関して)
>
> http://s2container.net.seasar.org/ja/quill.html#aop
> が、参考です。
>
> # ってさっき、自分がメーラーのエディタ上で
> # ささっと書いたやつにvirtualが付いてませんでしたね...
> # (すいません、普段はJavaプログラマなので)
>
> <2>
> InsertDBにて、クラスとメソッド両方に
> トランザクション属性がありますが、
> どちらか片方は除去して下さい。
> (とりあえず話を単純にするためにクラスの方を
> 除去して試して頂ければと)
>
> <3>
> InsertDBには、S2Dao属性は不要(!?)...だと思われます。
> S2Dao属性は、S2Daoで管理するDaoインターフェース
> にのみ付与するもののはずです。
> (間違ってたら誰か指摘して下さい)
>
> <4>
> InsertData()メソッド内で、色々ログを出力してみて、
> ログのトランザクション開始や終了がどのタイミングで
> 発生しているのかご確認下さい。
> (やはり、ログからはDAOにトランザクション属性が
> 付与されてしまっているように見えるので...)
>
> 2010/3/15 MOTO FUJI <[E-MAIL ADDRESS DELETED]>:
>> 久保さん
>>
>> ご回答有難うございます。
>>
>> 下記を参考にクラスを作成してみたのですが、
>> 一件毎にトランザクションがかかってしまいます。
>> ※DAOにはTransactionは付与していません。
>>
>> VB.NETですが、下記のソースに問題はありますか?
>>
>> <ソース>
>> Imports Seasar.Quill
>> Imports Seasar.Quill.Attrs
>> <Implementation()> _
>>    <S2Dao()> _
>>    <Transaction()> _
>> Public Class InsertDB
>>
>>    Private injector As QuillInjector = QuillInjector.GetInstance
>>    Protected daoOfInsert As InsertDao
>>
>> #Region "Public関数"
>>
>>    Public Sub New()
>>        injector.Inject(Me)
>>    End Sub
>>
>>    <Transaction()> _
>>    Public Function InsertData(ByVal dto As ImportDto()) As Boolean
>>        For i As Integer = 0 To dto.Length - 1
>>            daoOfInsert.InsertData(dto(i))
>>        Next
>>    End Function
>> End Class
>>
>> <ログ>
>> Seasar.Quill.Database.DataSource.Impl.SelectableDataSourceProxyWithDictionary
>> Debug:0] DataSourceName=[ds]
>> Seasar.Framework.Util.DataSourceUtil Log:0] Logical connection got
>> Seasar.Extension.Tx.Impl.TransactionContext Log:0] Transaction began
>> Seasar.Extension.ADO.Impl.BasicUpdateHandler Debug:0]
>>
>> 1件目のSQL文……
>>
>> Seasar.Extension.Tx.Impl.TransactionContext Log:0] Transaction committed
>> Seasar.Framework.Util.ConnectionUtil Log:0] Logical connection closed
>> Seasar.Quill.Database.DataSource.Impl.SelectableDataSourceProxyWithDictionary
>> Debug:0] DataSourceName=[ds]
>> Seasar.Framework.Util.DataSourceUtil Log:0] Logical connection got
>> Seasar.Extension.Tx.Impl.TransactionContext Log:0] Transaction began
>> Seasar.Extension.ADO.Impl.BasicUpdateHandler Debug:0]
>>
>> 2件目のSQL文……
>>
>> Seasar.Quill.Database.DataSource.Impl.SelectableDataSourceProxyWithDictionary
>> Debug:0] DataSourceName=[ds]
>> Seasar.Extension.Tx.Impl.TransactionContext Log:0] Transaction rolledback
>> Seasar.Framework.Util.ConnectionUtil Log:0] Logical connection closed
>> ※2回目のクエリはわざとエラーを発生させています。
>>
>> 2010年3月15日11:27 kubo <[E-MAIL ADDRESS DELETED]>:
>>> 久保(jflute)です。
>>>
>>>> 上記についてですが、解決方法をアドバイス頂けないでしょうか。
>>>> 初歩的な質問になってしまいますが、Webサービス以外のクラスでループを回しても
>>>> 結局はDAOから離れてしまうので同じ結果になってしまうことはありませんか?
>>>
>>> Webサービス以外のクラスに、トランザクション属性を付与して、
>>> (そのクラスは、DAOと同じようにQuillで管理するクラスであること)
>>> そのクラスの中でループを回してDAOを呼び出せば良いかと思います。
>>>
>>> 今は、「WEBサービスのクラス to DAO」になっていますが、
>>> 例えば、「WEBサービスのクラス to Facade to DAO」という構成にして、
>>> (仮に Facade という名前を付けるとして)
>>> Facadeに対してトランザクション属性を付与します。
>>> (逆にDAOには付与しなくてOKです)
>>>
>>> [Implementation()]
>>> [Transaction()]
>>> public class XxxFacade {
>>>
>>>    protected XxxDao xxxDao;
>>>    public void Yyy(...) {
>>>        for (...) {
>>>            xxxDao.InsertData();
>>>        }
>>>    }
>>> }
>>> ※VB書いたことないので、C#っぽくなってますが要領は同じです。
>>>
>>>> 申し訳ございませんが、どのような処理になるのか教えていただけないでしょうか?
>>>> ※すいません。イメージが湧きません。
>>>
>>> https://www.seasar.org/svn/sandbox/dbflute.net/trunk/dfnet-asp.net-example
>>> の「/source/DfExampleBiz/Facade/Member/MemberFacade.cs」が
>>> まさしく似たような構成になっていて、こちらはASP.NETですが、
>>> ASP.NETのPageクラスはQuill管理にできないので(AOPが掛けられない)、
>>> Facadeというレイヤを一枚用意して、そこでトランザクションを発生させて、
>>> Behavior(その奥にDaoがいます)を呼び出しています。
>>>
>>> 2010/3/15 MOTO FUJI <[E-MAIL ADDRESS DELETED]>:
>>>> 久保さん
>>>>
>>>> 比嘉です。
>>>>
>>>> 早速のご回答有難うございます。
>>>> 曖昧な質問をしてしまい、申し訳ございませんでした。
>>>> 次回からは具体的にどのような設定を行ったのかを記述したいと思います。
>>>>
>>>>> 少なくとも、DAOにトランザクションが掛かっていても、
>>>>> WEBサービスのクラスの中でループでメソッドを呼んでいる限りは、
>>>>> 前のメソッドと次のメソッドの処理の間に、一度DAOから離れた
>>>>> 処理が入っているので、どうしてもトランザクションは途切れるかと。
>>>>
>>>> なるほど、現在発生している現象は上記と同じことが言えますね。
>>>> おっしゃる通り、Webサービス側でループしているので1件目のデータ登録と
>>>> 2件目のデータ登録は別のトランザクションが発生しているということで理解しました。
>>>> ※ログを確認したのですが、ちゃんとトランザクションは掛かっていました。
>>>>
>>>> 上記についてですが、解決方法をアドバイス頂けないでしょうか。
>>>> 初歩的な質問になってしまいますが、Webサービス以外のクラスでループを回しても
>>>> 結局はDAOから離れてしまうので同じ結果になってしまうことはありませんか?
>>>> 申し訳ございませんが、どのような処理になるのか教えていただけないでしょうか?
>>>> ※すいません。イメージが湧きません。
>>>>
>>>> トランザクションの拡張後にエラーが発生する件についてですが、
>>>> まず上記の対応が解決しないと先に進めない為、保留とさせてください。
>>>> 私から質問しているのも関わらず、申し訳ございません。
>>>>
>>>> 2010年3月12日23:00 kubo <[E-MAIL ADDRESS DELETED]>:
>>>>> 久保(jflute)です。
>>>>>
>>>>>> 私が設定した内容だとDAOに定義されているすべてのメソッドに
>>>>>> トランザクションがかかるということで認識しました。
>>>>> 言葉の問題ですが「すべてのメソッドにトランザクションがかかる」
>>>>> というのは解釈次第でどちらにも取れるかもしれません。
>>>>
>>>>> 少なくとも、DAOにトランザクションが掛かっていても、
>>>>> WEBサービスのクラスの中でループでメソッドを呼んでいる限りは、
>>>>> 前のメソッドと次のメソッドの処理の間に、一度DAOから離れた
>>>>> 処理が入っているので、どうしてもトランザクションは途切れるかと。
>>>>>
>>>>>> 上記は、サンプルのソースですとWebサービスに記述する必要があるとことで
>>>>>> 宜しいでしょうか?
>>>>>
>>>>> WEBサービスのクラスがQuill管理であればYESですが、
>>>>> とにかくDI可能(Quill管理)なオブジェクトのクラスで
>>>>> ループを回すようにして下さい。
>>>>> WEBサービスのクラスにトランザクション属性を指定しても、
>>>>> そのトランザクション属性を解釈する人がいなければ無意味なので。
>>>>>
>>>>>> 話は変わりますが、トランザクションは拡張することができると思うのですが、
>>>>>> 下記のサイトを参考に、設定するとWebサービスが呼び出せなくなってしまう
>>>>>> 現象が発生しました。SoapExceptionが発生するのですが、原因は分かりますか?
>>>>>> <http://s2container.net.seasar.org/ja/quill.html#nodicon_tx>
>>>>> SoapExceptionのメッセージやスタックトレースを
>>>>> 提示するようにして下さい。(業務情報は伏せて)
>>>>> あと、具体的にどのような設定を行ったのかも提示しましょう。
>>>>> また、こういった込み入ったトラブルシューティングの場合は、
>>>>> 利用しているフレームワークの一覧とバージョンや周辺の環境など、
>>>>> 一通り提示する方が良いです。ちょっとこれだけの情報だと、
>>>>> このMLにWEBサービスに詳しい人がいたとしても答えづらいと思うので。
>>>>>
>>>>> 色々整理して書くのは大変だと思われますが、
>>>>> よろしくお願いします。
>>>>>
>>>>> 2010/3/12 MOTO FUJI <[E-MAIL ADDRESS DELETED]>:
>>>>>> 久保さん。こんばんは
>>>>>>
>>>>>> FUJIです。
>>>>>>
>>>>>> 早速のご回答有難うございます。
>>>>>> 私が設定した内容だとDAOに定義されているすべてのメソッドに
>>>>>> トランザクションがかかるということで認識しました。
>>>>>> 月曜日にログの内容を確認してみたいと思います。
>>>>>>
>>>>>>> InsertData呼び出す処理(Quillで管理されているクラス)にて
>>>>>>> トランザクション属性を付与するようにしてみて下さい。
>>>>>> 上記は、サンプルのソースですとWebサービスに記述する必要があるとことで
>>>>>> 宜しいでしょうか?
>>>>>>
>>>>>> 話は変わりますが、トランザクションは拡張することができると思うのですが、
>>>>>> 下記のサイトを参考に、設定するとWebサービスが呼び出せなくなってしまう
>>>>>> 現象が発生しました。SoapExceptionが発生するのですが、原因は分かりますか?
>>>>>> <http://s2container.net.seasar.org/ja/quill.html#nodicon_tx>
>>>>>>
>>>>>> 2010年3月12日18:47 kubo <[E-MAIL ADDRESS DELETED]>:
>>>>>>> 久保(jflute)です。
>>>>>>>
>>>>>>> FUJIさん、こんばんは
>>>>>>>
>>>>>>> まずは、ログでトランザクションの開始と終了(コミットなど)
>>>>>>> が、どういったタイミングで呼び出されているかご確認下さい。
>>>>>>>
>>>>>>> トランザクションをかける
>>>>>>> http://s2container.net.seasar.org/ja/quill.html#nodicon_tx
>>>>>>>
>>>>>>> 自分はあまりクラスに付けたことがないのですが、
>>>>>>> 恐らく
>>>>>>> 「クラスの全てのメソッドにトランザクションAOPが掛かる」
>>>>>>> ということだと思うので、
>>>>>>> 「InsertData呼び出し単位」でのトランザクションで
>>>>>>> あることに変わりはないと思われます。
>>>>>>> (InsertDataメソッドの属性を付与するのと同じ)
>>>>>>> InsertData呼び出す処理(Quillで管理されているクラス)にて
>>>>>>> トランザクション属性を付与するようにしてみて下さい。
>>>>>>>
>>>>>>> 2010/3/12 MOTO FUJI <[E-MAIL ADDRESS DELETED]>:
>>>>>>>> はじめまして、FUJIといいます。
>>>>>>>>
>>>>>>>> VB.NETを利用しているのですが、トランザクションがかからずに困っています。
>>>>>>>> アドバイスを頂けないでしょうか。
>>>>>>>> WebサービスからDAOのメソッドを呼び出し、データをINSERTする処理になっています。
>>>>>>>> 外部ファイルに記述されたINSERT文を発行するのですが発行後、データの追加できるのですが、
>>>>>>>> 2件目のデータを追加する際に、エラーを発生させるとロールバックされずに1件目のデータが
>>>>>>>> 追加された状態となっています。※ストアドで追加を行っても同じ現象が発生しました。
>>>>>>>> DAOのInsertDataメソッドに<Transaction()>を指定した場合は、上記のように1件目が
>>>>>>>> 登録されると思うのですが、<Transaction()>はクラスに指定を行っているので、
>>>>>>>> ロールバックされると思っていたのですが誤りでしょうか?
>>>>>>>> //DAO Start
>>>>>>>> Imports Seasar.Dao.Attrs
>>>>>>>> Imports Seasar.Quill.Attrs
>>>>>>>>
>>>>>>>> <Implementation()> _
>>>>>>>> <S2Dao()> _
>>>>>>>>   <Transaction()> _
>>>>>>>>   <Bean(GetType(SampleDto))> _
>>>>>>>> Public Interface SampleDao
>>>>>>>>
>>>>>>>> <SqlFile()> _
>>>>>>>> Function InsertData(ByVal InsData As SampleDto) As Boolean
>>>>>>>>
>>>>>>>> End Interface
>>>>>>>>
>>>>>>>> //DAO End
>>>>>>>> ------------------------------------------------------------------------------------------
>>>>>>>> //DTO Start
>>>>>>>> Imports Seasar.Dao.Attrs
>>>>>>>>
>>>>>>>> Namespace Sample
>>>>>>>>
>>>>>>>>   Public Class SampleDto
>>>>>>>>
>>>>>>>> Public Property TelNumber() As String
>>>>>>>> Get
>>>>>>>> Return _TelNumber
>>>>>>>> End Get
>>>>>>>> Set(ByVal value As String)
>>>>>>>> _TelNumber = value
>>>>>>>> End Set
>>>>>>>> End Property
>>>>>>>>
>>>>>>>> //DTO End
>>>>>>>> ------------------------------------------------------------------------------------------
>>>>>>>> //WEBサービス Start
>>>>>>>> Imports System.Web
>>>>>>>> Imports System.Web.Services
>>>>>>>> Imports System.Web.Services.Protocols
>>>>>>>> Imports Seasar.Quill
>>>>>>>> Imports Seasar.Quill.Attrs
>>>>>>>> Imports System.Security.Cryptography
>>>>>>>> Imports System.Collections.Generic
>>>>>>>>
>>>>>>>> <WebService(Namespace:="http://localhost.WebService/")> _
>>>>>>>> <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
>>>>>>>> <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
>>>>>>>> Public Class WebService01
>>>>>>>> Inherits System.Web.Services.WebService
>>>>>>>>
>>>>>>>> Protected daoOfSample As SampleDao
>>>>>>>> Private Function ImportData(ByVal _strTelnumber As String) As Boolean
>>>>>>>> Dim dto(2) as SampleDto
>>>>>>>> dto(0).TelNumber = "090-xxxx-xxxx"
>>>>>>>> dto(1).TelNumber = "080-xxxx-xxxx"
>>>>>>>> For i as integer = 0 To dto.Length -1
>>>>>>>>    daoOfSample.InsertData(dto(i))
>>>>>>>> Next
>>>>>>>> End Sub
>>>>>>>> //WEBサービス End
>>>>>>>> _______________________________________________
>>>>>>>> seasar-dotnet mailing list
>>>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>>>
>>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> seasar-dotnet mailing list
>>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>>
>>>>>> _______________________________________________
>>>>>> seasar-dotnet mailing list
>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>
>>>>> _______________________________________________
>>>>> seasar-dotnet mailing list
>>>>> [E-MAIL ADDRESS DELETED]
>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>
>>>> _______________________________________________
>>>> seasar-dotnet mailing list
>>>> [E-MAIL ADDRESS DELETED]
>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>
>>> _______________________________________________
>>> seasar-dotnet mailing list
>>> [E-MAIL ADDRESS DELETED]
>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>
>> _______________________________________________
>> seasar-dotnet mailing list
>> [E-MAIL ADDRESS DELETED]
>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>
> _______________________________________________
> seasar-dotnet mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>



-- 
--
西山はじめ


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