[seasar-dotnet:2122] Re: QuillのDAO機能でデータベース接続が取得できない

ASO Katsumi [E-MAIL ADDRESS DELETED]
2011年 12月 13日 (火) 20:37:03 JST


西山さん
Replyありがとうございます。ASOです。

さっとWeb検索してみただけですが、キーワード的には
“ServiceHostFactoryBase”や“Opening”“Closing”、あるいは“IServiceBehavior”
などが当たりますでしょうか?
# ご記憶にある範囲で結構ですので、ご回答頂けると幸いです。

現在、手元でも「リクエストを受けた段階でログ出力する」という目的のため、
ServiceHostFactoryBaseのサブクラスや、IServiceBehaviorの実装クラスを作ったりはしています。
# 正確には同僚に作ってもらいました。

あと、IDispatchMessageInspectorの実装クラスで、AfterReceiveRequestメソッドやBeforeSendReply
メソッドのOverridesも実装しています。

当方でも、実装実験は行って参りますが、上記のうちで、“あぁ、その辺り”など、
思い当るところがあれば、ご教示下さい。

以上、よろしくお願い致します。


On Tue, 13 Dec 2011 14:24:29 +0900, 西山はじめ <[E-MAIL ADDRESS DELETED]> wrote:
> 西山(hajimeni)です。
> 
> うろ覚えですが、同じような構成(Windowsアプリ+WCF+IIS+Quill)で構築した覚えがあります。
> WCFをIISに載せたときには、接続ごとかセッションごとに初期化コードがどこかで書けたはずで、そこでServiceをNewしてInjectしないとタイムアウト等で同じようなことになった気がします。
> 
> 自分の周囲の環境が変わってしまい、そのソースが現在手に入らないので、確認できない為、あやふやな回答になってしまい申し訳ありません。
> 何らかの情報になれば幸いです。
> 
> --
> 西山はじめ
> 
> 
> 
> 2011年12月13日10:48 ASO Katsumi <[E-MAIL ADDRESS DELETED]>:
>> 小谷さん
>> Replyが遅くなり、申し訳ありません。
>>
>> ご提案頂いた4案とも(C,Dについては各2案とも)
>> 「Seasar.Framework.Container.Factory.ClassNotFoundRuntimeException」例外が発生しました。
>> いずれも“タイムアウト後”にです。
>>
>>> ・タイムアウト=WCFサービスのタイムアウト
>>> ・タイムアウト後に問題発生→タイムアウトしなければ複数回サービスを呼び出しても正常に動作する
>>
>> この2点につきましては、ご理解頂いている通りです。
>> タイムアウト時間を長く取れば、運用・利用上は問題無いように見せる事が出来るとは考えていますが、
>> 起きると分かっている問題を放っておく事もできず、解決を目指しています。
>>
>> 情報ポインタだけでも結構です。ご存知の事がございましたら、お知らせ下さい。 > ALL
>> 改めて、よろしくお願いします。
>>
>> 以下余談。
>> 先週末から風邪でダウンしたりしていました。
>> 皆さんもご自愛下さい。
>>
>>
>> On Wed, 7 Dec 2011 23:03:45 +0900, "kotani.k" <[E-MAIL ADDRESS DELETED]> wrote:
>>> ASOさん
>>>
>>> 小谷です。
>>>
>>> ご確認、ソースのご提示ありがとうございます。
>>> タイムアウト後に「ClassNotFoundRuntimeException」が発生するということは
>>> セッションが切れるとロードしたアセンブリの情報が失われてしまっているのかもしれません。
>>> (こちらも手探りのため、曖昧な言い回しになってしまっています。ごめんなさい)
>>>
>>> 下記のような修正をそれぞれ行った場合は如何でしょうか?
>>> (WCFサービスに詳しい方、もしアドバイス等ありましたら是非ともお願い致します)
>>>
>>> A.WCFサービスを実装しているプロジェクトの参照設定でODP.NETのライブラリを参照するようにする
>>>
>>> B.MainService#Loginの最初に下記コードを実行する
>>>    Seasar.Quill.QuillConfig.GetInstance().RegisterAssembly();
>>>    (↑QuillContainerのインスタンスが作られたときにアセンブリをロードしている処理です)
>>>
>>> C.「 <Aaaaa.Bbbbbb.Server.Extends.MyServiceBehavior()>」がServiceBehavior属性を拡張したものという前提になりますが、
>>>       下記のように引数を指定する
>>>    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
>>>    もしくは[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
>>>
>>> D.同様にSeriviceBehavior属性の引数を下記のように指定する
>>>  [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
>>>  もしくは[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
>>>
>>> それと、今更ながら一応確認させていただきたいのですが、
>>>
>>> ・タイムアウト=WCFサービスのタイムアウト
>>> ・タイムアウト後に問題発生→タイムアウトしなければ複数回サービスを呼び出しても正常に動作する
>>>
>>> という認識でよろしいでしょうか?
>>>
>>> 以上です。
>>> よろしくお願いします。
>>>
>>> 2011年12月7日14:21 ASO Katsumi <[E-MAIL ADDRESS DELETED]>:
>>>> 小谷さん
>>>> Replyありがとうございます、ASOです。
>>>>
>>>>> 1.Implementation属性を設定しているということは、
>>>>>  どこかでServiceContractに対してQuillInjectorのInjectメソッドを使ってインジェクションをしている箇所があると思うのですが、
>>>>>  それはどちらで行っているでしょうか?
>>>>
>>>> ServiceContractはWCFサービスを定義するインターフェースで、インジェクションはそのインターフェースの実装クラスの
>>>> コンストラクタ(New())で行っています。
>>>>
>>>> 現在のソース上から、該当部分の記述を抜粋します。
>>>> # 明らかにできない情報を伏せたり、一部簡略化したり、例外処理を省略したりしていますが、概ね実物どおりです。
>>>>
>>>> ---- IMainService.vb    # WCFサービスインターフェース
>>>>  1:Namespace Aaaaa.Bbbbbb.MainService
>>>>  2:    <ServiceContract()>
>>>>  3:    Public Interface IMainService
>>>>  4:        <OperationContract()>
>>>>  5:        Function Login(ByVal req As OriginalRequestType) As OriginalResponseType
>>>>  6:    End Interface
>>>>  7:End Namespace
>>>>
>>>> ---- MainService.vb     # WCFサービスクラス
>>>>  1:Namespace Aaaaa.Bbbbbb.MainService
>>>>  2:    <Aaaaa.Bbbbbb.Server.Extends.MyServiceBehavior()>
>>>>  3:    Public Class MainService
>>>>  4:        Implements IMainService
>>>>  5:
>>>>  6:        Protected loginFacade As BizFacade.ILoginFacade
>>>>  7:
>>>>  8:        Public Sub New()
>>>>  9:            QuillInjector.GetInstance().Inject(Me)
>>>> 10:        End Sub
>>>> 11:
>>>> 12:        Public Function Login(ByVal req As OriginalRequestType)
>>>>  :                             As OriginalResponseType Implements IMainService.Login
>>>> 13:            Dim res As OriginalRequestType
>>>> 14:            res = loginFacade.Execute(req)
>>>> 15:            Return res
>>>> 16:        End Function
>>>> 17:    End Class
>>>> 18:End Namespace
>>>>
>>>>> 2.下記のような修正を行って実行した場合は如何でしょうか?
>>>>
>>>> 上記、MainService.vbを次のように改造しました(*1〜*3の部分)。
>>>> ---- MainService.vb     # 改造版
>>>> 12:        Public Function Login(ByVal req As OriginalRequestType)
>>>>  :                             As OriginalResponseType Implements IMainService.Login
>>>> 13:            Dim res As OriginalRequestType
>>>> *1:            Dim localLogin As BizFacade.ILoginFacade
>>>> *2:            localLogin = ComponentUtil.GetComponent(QuillInjector.GetInstance.Container, GetType(BizFacade.ILoginFacade))
>>>> 14:            'res = loginFacade.Execute(req)  元のソースはコメントアウト
>>>> *3:            res = localLogin.Execute(req)
>>>> 15:            Return res
>>>> 16:        End Function
>>>>
>>>> 試してみましたところ、*3の部分で、例外が発生しました。
>>>> やはり、1回目は成功して、タイムアウト後に同じサービスを呼び出した時に問題が起こります。
>>>>
>>>> 以上で、ご要望に沿った内容になっておりますでしょうか?
>>>> 他にも情報が必要であれば、お知らせ下さい。
>>>>
>>>> 念のため、ILoginFacadeインターフェースとその実装も記載しておきます。
>>>>
>>>> ---- ILoginFacade.vb
>>>>  1:Namespace Aaaaa.Bbbbbb.MainService.BizFacade
>>>>  2:    <Implementation(GetType(LoginFacade))>
>>>>  3:    Public Interface ILoginFacade
>>>>  4:        Inherits Aaaaa.Bbbbbb.Server.IBizFacade
>>>>  :                 '↑「Function Execute(ByVal req As Models.RequstParameter) As OriginalResponseType」の宣言のみ
>>>>  5:    End Interface
>>>>  6:End Namespace
>>>>
>>>> ---- LoginFacade.vb
>>>>  1:Namespace Aaaaa.Bbbbbb.MainService.BizFacade
>>>>  2:    <Implementation()>
>>>>  3:    Public Class LoginFacade
>>>>  4:        Inherits Aaaaa.Bbbbbb.Server.BizFacade
>>>>  :                 '↑「Public MustOverride Function Execute(ByVal req As Models.RequstParameter)
>>>>  :                 '         As OriginalResponseType Implements Aaaaa.Bbbbbb.Server.IBizFacade.Execute」を定義
>>>>  5:        Implements ILoginFacade
>>>>  6:
>>>>  7:        Protected loginLogic As BizLogic.ILoginLogic
>>>>  8:
>>>>  9:        <Transaction()>
>>>> 10:        <Aspect(GetType(Aaaaa.Bbbbbb.Server.LogAop))>        '←メソッドの実行開始/終了ログ出力 (IMethodInterceptor)
>>>> 11:        Public Overrides Function Execute(ByVal req As Models.RequstParameter) As OriginalResponseType
>>>> 12:            Dim res As OriginalResponseType
>>>> 13:
>>>> 14:            'ユーザ権限情報の取得
>>>> 15:            Dim userinfo As UserInfo = loginLogic.GetUserInfo(req.UserInfo)
>>>> 16:            res = New OriginalResponseType(userinfo)
>>>> 17:
>>>> 18:            res.ApiResult = API_RESULT.SUCCESS
>>>> 19:            Return res
>>>> 20:        End Function
>>>> 21:    End Class
>>>> 22:End Namespace
>>>>
>>>> 引き続き、よろしくお願い致します。
>>>>
>>>>
>>>> On Wed, 7 Dec 2011 00:25:17 +0900, "kotani.k" <[E-MAIL ADDRESS DELETED]> wrote:
>>>>> ASOさん
>>>>>
>>>>> こんにちは。小谷です。
>>>>>
>>>>> お手数ですが、状況の確認のため二点ご確認させて下さい。
>>>>>
>>>>> 1.Implementation属性を設定しているということは、
>>>>>  どこかでServiceContractに対してQuillInjectorのInjectメソッドを使ってインジェクションをしている箇所があると思うのですが、
>>>>>  それはどちらで行っているでしょうか?
>>>>>
>>>>>
>>>>> 2.下記のような修正を行って実行した場合は如何でしょうか?
>>>>>
>>>>> ServiceContract, OperationContract属性を設定しているクラスからQuill, Seasar.NET関係の属性を外す
>>>>>>>>>> LoginメソッドをもつHogeFacadeクラスを作成して
>>>>> Aaaaa.Bbbbbb.MainService.MainService.Login内で行っている処理をHogeFacade#Loginに移す
>>>>>>>>>> HogeFacade#LoginにTransacton,Aspect属性を設定
>>>>>>>>>> Aaaaa.Bbbbbb.MainService.MainService.Login内で
>>>>> HogeFacadeのインスタンスを下記のようにして取得
>>>>> var facade = (HogeFacade)ComponentUtil.GetComponent(QuillInjector.GetInstance().Container,
>>>>> typeof(HogeFacade));
>>>>>>>>>> facade.Loginメソッドを呼び出す
>>>>>
>>>>> 2011年12月6日16:53 ASO Katsumi <[E-MAIL ADDRESS DELETED]>:
>>>>>> こんにちは、ASOです。
>>>>>>
>>>>>> 現在、WCF+Oracle(ODP)+S2(Quill)でWCFサービス開発を行っています。
>>>>>> 作成したWCFサービスを、IIS上に配置し、
>>>>>> 1 初回アクセスは問題無く動作する。
>>>>>> 2 サービスのタイムアウトを待つ。
>>>>>> 3 再度同じサービスにアクセスする。
>>>>>> という操作を行ったところ、3の段階で
>>>>>> 「Seasar.Framework.Container.Factory.ClassNotFoundRuntimeException」例外が発生し、処理が中断されます。
>>>>>> 「詳細は "Oracle.DataAccess.Client.OracleConnection"」との事です。
>>>>>> # ログに記録されたStackTraceを文末に掲載します。
>>>>>>
>>>>>> この現象を回避するか、あるいは原因を突き止め対策したいと思っており、
>>>>>> 情報収集していますが、これといったリソースを見つけられず、MLで相談しようと
>>>>>> 考えた次第です。
>>>>>>
>>>>>> 動作環境は次の通りです。
>>>>>>  Windows Server 2008 R2
>>>>>>  IIS 7.5
>>>>>>  .NET Framework V4
>>>>>>  WCF
>>>>>>  Seasa2.NET 1.4.0 RC2 改 ([seasar-dotnet:2093]で井上さんに教えて頂いた内容です)
>>>>>>
>>>>>>  Oracle 11g
>>>>>>  ODP (32bit)
>>>>>> 以上。
>>>>>>
>>>>>> ログ中の「Aaaaa.Bbbbbb.MainService.MainService」というクラスがServiceContractであり、
>>>>>> Implementation属性を付けてあります。
>>>>>>
>>>>>> 同じくログ中の「Aaaaa.Bbbbbb.MainService.MainService.Login」というメソッドがOperationContractであり、
>>>>>> Transaction、Aspect(ログ出力インターセプタークラス)という各属性が付いています。
>>>>>>
>>>>>> 何か、お気付きの事があればお知らせ下さい。
>>>>>> 情報の不足がございましたら、ご指導下さい。
>>>>>> 情報ポインタをご紹介頂くだけでも結構です。
>>>>>> よろしくお願い致します。
>>>>>>
>>>>>> 以下、StackTraceです。
>>>>>> 2011-12-06 12:14:48,188 ERROR Server-Name request-userid [EXCEPTION] Aaaaa.Bbbbbb.MainService.MainService.Login [ESSR0071]SQLで例外が発生しました。理由はSeasar.Framework.Container.Factory.ClassNotFoundRuntimeException: [ESSR0044]クラスが見つかりませんでした。詳細は "Oracle.DataAccess.Client.OracleConnection"
>>>>>>   at Seasar.Extension.ADO.Impl.DataProviderDataSource.ForName(String name)
>>>>>>   at Seasar.Extension.ADO.Impl.DataProviderDataSource.GetConnection()
>>>>>>   at Seasar.Extension.Tx.Impl.TxDataSource.GetConnection()
>>>>>>   at Seasar.Extension.ADO.Impl.AbstractSelectableDataSourceProxy.GetConnection()
>>>>>>   at Seasar.Framework.Util.DataSourceUtil.GetConnection(IDataSource dataSource)
>>>>>> 2011-12-06 12:14:48,188 ERROR Server-Name request-userid [EXCEPTION] Aaaaa.Bbbbbb.MainService.MainService.Login Seasar
>>>>>> 2011-12-06 12:14:48,188 ERROR Server-Name request-userid [EXCEPTION] Aaaaa.Bbbbbb.MainService.MainService.Login    at Seasar.Framework.Util.DataSourceUtil.GetConnection(IDataSource dataSource)
>>>>>>   at Seasar.Extension.Tx.Impl.TransactionContext.OpenConnection()
>>>>>>   at Seasar.Extension.Tx.Impl.TransactionContext.Begin()
>>>>>>   at Seasar.Extension.Tx.Impl.LocalRequiredTxHandler.HandleTransaction(IMethodInvocation invocation)
>>>>>>   at Seasar.Extension.Tx.Impl.LocalRequiredTxHandler.Handle(IMethodInvocation invocation, Boolean alreadyInTransaction)
>>>>>>   at Seasar.Extension.Tx.TransactionInterceptor.Invoke(IMethodInvocation invocation)
>>>>>>   at Seasar.Framework.Aop.Impl.DynamicProxyMethodInvocation.Proceed()
>>>>>>   at Aaaaa.Bbbbbb.Server.LogAop.Invoke(IMethodInvocation invocation) in C:\Aaaaa\Source\Aaaaa.Bbbbbb.Server\Aaaaa\LogAop.vb:line 63
>>>>>>   at Seasar.Framework.Aop.Impl.InterceptorAdapter.Intercept(IInvocation invocation)
>>>>>>   at Castle.DynamicProxy.AbstractInvocation.Proceed()
>>>>>>   at Castle.Proxies.LoginFacadeProxy.Execute(RequstParameter req)
>>>>>>   at Aaaaa.Bbbbbb.MainService.MainService.Login(RequstParameter req) in C:\Aaaaa\Source\Aaaaa.Bbbbbb.MainService\Aaaaa\MainService.svc.vb:line 39
>>>>>>
>>>>>> _______________________________________________
>>>>>> 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 メーリングリストの案内