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

kotani.k [E-MAIL ADDRESS DELETED]
2011年 12月 7日 (水) 23:03:45 JST


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 メーリングリストの案内