предотвратить возврат того же объекта в то же время в db4o - PullRequest
1 голос
/ 12 августа 2010

Я использую db4o в веб-приложении asp.net, как вы знаете, когда db4o возвращает список объектов, которые они не упорядочены.

на моем веб-сайте я запускаю запрос и получаю последний объект врезультаты и работа над ним (некоторая обработка, а затем обновление одного из его полей).

Мой вопрос заключается в том, если, когда я работаю над этим объектом, если другой пользователь приедет и снова выполнит этот запрос, тот же объектвозвращается к нему, и оба пользователя получают один и тот же объект.

Я не хочу, чтобы это произошло.как я могу предотвратить это?

Ответы [ 2 ]

1 голос
/ 12 августа 2010

Не уверен, что DB4O предоставляет что-то подобное из коробки, но может сам реализовать какую-то пессимистическую блокировку, при которой тот же объект либо не будет возвращен, либо будет возвращен в режиме только для чтения. Вам нужно будет вести список редактируемых объектов и проверять этот список каждый раз, когда вы возвращаете свои объекты. Но есть и такие проблемы, как уход пользователей и застревание объектов в «режиме редактирования» и т. Д. Обычно для этого требуется какой-то сервис, включающий механизм тайм-аута. Это может быть сложно.

Или сделайте это с оптимизмом, например пусть оба пользователя редактируют его, но сохраняют изменения только от первого пользователя, и предупреждают второго пользователя при попытке сохранить его. Обычно делается с отметкой времени.

Редактировать

Чтобы привести конкретный пример, этот код C # предоставляет базовый способ «заблокировать» объект, чтобы он не возвращался каждый раз. В реальной жизни все будет сложнее.

using System;
using System.Collections.Generic;
using System.Linq;

namespace ListTest
{
    class Program
    {
        static void Main(string[] args)
        {
            DataAccess dataAccess = new DataAccess();

            // get objects from database
            List<MyThing> things = dataAccess.GetThings();
            MyThing thingToWorkOn = things[things.Count-1];
            printThingList(things);

            // lock the object to work on
            dataAccess.LockThing(thingToWorkOn);

            // someone else gets the list - doesn't include thing being edited
            List<MyThing> moreThings = dataAccess.GetThings();
            printThingList(moreThings);

            // edit the object
            thingToWorkOn.Name = "Harrold";
            thingToWorkOn.Name = "Harry";

            // save the object and unlock it
            dataAccess.Save(thingToWorkOn);
            dataAccess.UnlockThing(thingToWorkOn);

            // now when someone else gets the list, includes all objects
            List<MyThing> evenMoreThings = dataAccess.GetThings();
            printThingList(evenMoreThings);
        }

        static void printThingList(List<MyThing> things)
        {
            Console.WriteLine("* Things *");
            things.ForEach(x => Console.WriteLine(x.Name));
            Console.WriteLine();
        }
    }

    // The objects you're working with.  Could just use 'object' or some interface.
    class MyThing : IEquatable<MyThing>
    {
        public string Name { get; set; }

        public bool Equals(MyThing other)
        {
            return other.Name == this.Name;
        }
    }

    // Class to get objects from database.
    class DataAccess
    {
        // simple list to store 'locked' objects
        private static List<MyThing> lockedThings = new List<MyThing>();

        // Get all objects except the locked ones
        public List<MyThing> GetThings()
        {
            List<MyThing> thingsFromDatabase = LoadThingsFromDatabase();

            var nonLockedThings = (from thing in thingsFromDatabase
                                   where !lockedThings.Contains(thing)
                                   select thing
                                    ).ToList<MyThing>();

            return nonLockedThings;
        }

        // lock an object so it can't be seen by anyone else
        public void LockThing(MyThing thingToLock)
        {
            lockedThings.Add(thingToLock);
        }

        // unlock an object
        public void UnlockThing(MyThing thingToLock)
        {
            lockedThings.Remove(thingToLock);
        }

        public void Save(MyThing thing)
        {
            // save to database
        }

        // dummy method to give us some objects
        private List<MyThing> LoadThingsFromDatabase()
        {
            return new List<MyThing>() {
                new MyThing(){ Name="Tom" },
                new MyThing(){ Name="Dick" },
                new MyThing(){ Name="Harry" }
            };
        }
    }
}
0 голосов
/ 15 июня 2011

Вы можете реализовать базовую систему блокировки, используя поддержку обмена сообщениями вне диапазона, встроенную в db4o. Приведенный выше список Гранта может быть реализован на сервере db4o. Клиенты отправляют на сервер сообщение «Я хочу отредактировать объект x», и сервер пытается поместить объект в свой список. Если это удастся, он ответит сообщением «Да, вперед», в противном случае он может ответить «Нет, попробуйте позже». Когда клиент закончит редактирование, он отправит на сервер сообщение «Я закончил с объектом x».

...