0

NHibernates キャッシング/データベース ヒット防止技術の機能のいくつかを把握するのに苦労しています。

Web サービス API が新しいオブジェクトを適切に作成して保存することを確認するためのテスト ケースを作成しました。テスト ケースは、Web サービスを介してシリアル化する必要がない場合 (たとえば、Web サービス クラスをサービス参照として追加してアップ/ダウンするのではなく、Web サービス クラスを直接操作する場合) に合格します。しかし、ホステッド Web サービスに対してテスト ケースを実行すると、NHibernate から古いデータを受け取ります。

[Test]
public void CreateInstallTask()
{
    int numberOfTasks = TaskDao.GetAll().Count();

    TaskDto taskDto = WorkflowServices.CreateInstallTask(OrderID, TaskTemplateID, SiteID, DataCenterID,
                                                            DeviceTemplateID, DeviceName, Username);

    if (TaskDao.GetAll().Count() == numberOfTasks)
    {
        string failureReason =
            string.Format("Failed to create new Install task with OrderID: {0}", taskDto.OrderID);

        throw new Exception(failureReason);
    }
}

[WebMethod(Description = "Creates a new install Task.")]
public TaskDto CreateInstallTask(int orderID, int taskTemplateID, int siteID, int dataCenterID,
    int deviceTemplateID, string deviceName, string username)
{
    try
    {
        Order order = OrderDao.GetByID(orderID, shouldLock: false);

        if (order == null)
            throw new Exception(string.Format("Failed to find an order with ID {0}", orderID));

        Task task = new Task
            {
                Order = order,
                TaskType = TaskType.Install,
                TaskTemplateID = taskTemplateID,
                CreateUserID = username,
                CreateDateTime = DateTime.Now
            };

        TaskAction taskAction = new TaskAction(TaskDao, TaskDeviceDao, ActivityDao, task, username);
        //Call TaskDto.Create to convert Task into TaskDto for client-side use.
        return TaskDto.Create(taskAction.CreateTask());
    }
    catch (Exception exception)
    {
        Logger.Error(exception);
        throw;
    }
}

GetAll() メソッドは、テーブル内のすべての行に対する単なる criteria.List() です。CreateTask メソッドは ISession.SaveOrUpdate(); を呼び出すだけです。

データを強制的にリロードできることは理解していますが、なぜこれを行う必要があるのか​​わかりません。

SaveOrUpdate(entity) を呼び出すと、そのエンティティは NHibernate のキャッシュに自動的に追加されるはずですよね? TaskDao.GetAll() が古いデータを返すのはなぜですか?

CommitTransaction() の使いすぎが心配です。SaveOrUpdate() のたびに CommitTransaction() を呼び出す必要はないと思います。これは、NHibernates のキャッシュの目的を無効にします。しかし、テスト ケースにも古いデータは必要ありません。キャッシュの同期を維持するにはどうすればよいですか?

4

1 に答える 1

2

保存するたびにトランザクションをコミットするべきではないという点で正しいですが、Web サービスは Web 呼び出しの開始時に新しいトランザクションを作成し、Web 呼び出しの終了時にコミットする必要があります。

通常、Web サービスは、Web サイトが通常従うリクエストごとのセッションと同じパターンに従います。そのため、Web サービス インフラストラクチャが新しい NHibernate ISession を作成し、リクエストごとに新しいトランザクションを開始していることを確認してください。そのリクエストの最後に、行われた変更をコミットする必要があります。

于 2012-09-14T18:59:05.860 に答える