LINQ to SQL в многопоточном приложении
От: Obukhov Россия  
Дата: 02.12.11 12:52
Оценка:
База SQLite через "ADO.NET 3.5SP1 Entity Framework support for SQLite"
В приложении есть объет базы содержаший DataContext

Соединяюсь с БД в gui потоке,
Создаю и модифицирую объекты как в gui, так и в дочерних потоках.

После каждого изменения объекта вызываю
dataContext.SubmitChanges( ConflictMode.ContinueOnConflict );

как в основном, так и в дочерних потоках.

Переодически натыкаюсь на такие баги:

1) вываливаются исключения ChangeConflictException — борюсь с помощью
dataContext.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);

и затем повторно SubmitChanges
НО! при этом реально в БД эти данные остаются старыми (как будто я никаких ResolveAll не вызывал и повторно не сабмитил)

2) По завершения работы дочерних потоков, в главном потоке меняю состояние результирующего объекта и делаю submit — исключений не возникает,
но после повторного запуска приложения получаю предпоследнее состояние результирующего объекта !! WTF !!!

Может кто сталкивался с многопоточностью в LINQ to SQL ?
Помогите советом.
Re: LINQ to SQL в многопоточном приложении
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 02.12.11 12:58
Оценка:
Здравствуйте, Obukhov, Вы писали:


O>База SQLite через "ADO.NET 3.5SP1 Entity Framework support for SQLite"

O>В приложении есть объет базы содержаший DataContext

O>Может кто сталкивался с многопоточностью в LINQ to SQL ?

O>Помогите советом.


У вас DataContext один на все потоки или разные? Я делал на каждый новый поток свой DataContext, у меня для 50 потоков примерно 5 параллельных подключений к sql висит в пуле. Но в таком случае при использовании OptimisticConcurrency возможны указанные ошибки, так как если одни и те же данные сначала были загружены несколькими потоками и потом были изменены, то все, кроме первого, получат отказ в применении изменений.
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re: LINQ to SQL в многопоточном приложении
От: Obukhov Россия  
Дата: 02.12.11 12:59
Оценка:
Уточню,

сабмит выглядит так

lock (dataContext)
{
    try
    {
        dataContext.SubmitChanges(ConflictMode.ContinueOnConflict);
    }
    catch (ChangeConflictException e)
    {
        Logger.Error(String.Format("SubmitChanges:Optimistic concurrency error: [{0}]", e.Message));
        dataContext.ChangeConflicts.ResolveAll(RefreshMode.KeepCurrentValues);
        {
            try
            {
                dataContext.SubmitChanges();
            }
            catch (ChangeConflictException ex)
            {
                Logger.Error(String.Format("SubmitChanges:DOUBLE Сoncurrency error: [{0}]", ex.Message));
                throw new DataBaseException("Database error. Cannot resolve Сoncurrency error.", e, entity);
            }
        }

    }
}
Re[2]: LINQ to SQL в многопоточном приложении
От: Obukhov Россия  
Дата: 02.12.11 13:03
Оценка:
Здравствуйте, Sshur, Вы писали:

S>У вас DataContext один на все потоки или разные? Я делал на каждый новый поток свой DataContext, у меня для 50 потоков примерно 5 параллельных подключений к sql висит в пуле. Но в таком случае при использовании OptimisticConcurrency возможны указанные ошибки, так как если одни и те же данные сначала были загружены несколькими потоками и потом были изменены, то все, кроме первого, получат отказ в применении изменений.



DataContext один на всех, обслуживают 2-3 потока.

В том то и дело, что каждый поток меняет данные, выданные ему из очереди.
Объект попасть в соседний поток не сможет.
Re[3]: LINQ to SQL в многопоточном приложении
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 02.12.11 13:05
Оценка:
Здравствуйте, Obukhov, Вы писали:

O>Здравствуйте, Sshur, Вы писали:


S>>У вас DataContext один на все потоки или разные? Я делал на каждый новый поток свой DataContext, у меня для 50 потоков примерно 5 параллельных подключений к sql висит в пуле. Но в таком случае при использовании OptimisticConcurrency возможны указанные ошибки, так как если одни и те же данные сначала были загружены несколькими потоками и потом были изменены, то все, кроме первого, получат отказ в применении изменений.



O>DataContext один на всех, обслуживают 2-3 потока.


O>В том то и дело, что каждый поток меняет данные, выданные ему из очереди.

O>Объект попасть в соседний поток не сможет.

Что значит "выданные из очереди" ?

И вопрос, для вас важна OptimisticConcurrency или нет? Можно её просто отключить и проблем не будет. Но тогда изменения, сделанные одним потоком, могут быть потерты другими.
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[3]: LINQ to SQL в многопоточном приложении
От: Lloyd Россия  
Дата: 02.12.11 13:06
Оценка:
Здравствуйте, Obukhov, Вы писали:

S>>У вас DataContext один на все потоки или разные? Я делал на каждый новый поток свой DataContext, у меня для 50 потоков примерно 5 параллельных подключений к sql висит в пуле. Но в таком случае при использовании OptimisticConcurrency возможны указанные ошибки, так как если одни и те же данные сначала были загружены несколькими потоками и потом были изменены, то все, кроме первого, получат отказ в применении изменений.



O>DataContext один на всех, обслуживают 2-3 потока.


Any instance members are not guaranteed to be thread safe.

Re[4]: LINQ to SQL в многопоточном приложении
От: Obukhov Россия  
Дата: 02.12.11 13:14
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>

L>Any instance members are not guaranteed to be thread safe.


Thank you very much
Re[4]: LINQ to SQL в многопоточном приложении
От: Obukhov Россия  
Дата: 02.12.11 13:17
Оценка:
Здравствуйте, Sshur, Вы писали:

S>Что значит "выданные из очереди" ?


S>И вопрос, для вас важна OptimisticConcurrency или нет? Можно её просто отключить и проблем не будет. Но тогда изменения, сделанные одним потоком, могут быть потерты другими.


Сделана очередь, которая выдаёт объекты из списка необработанных, по порядку, пока не закончится итератор.
OptimisticConcurrency мне подходит, и собственно делаю ResolveAll(RefreshMode.KeepCurrentValues); но именно эти Cyrrent values в Бд в итоге не попадают!
Re[3]: LINQ to SQL в многопоточном приложении
От: HowardLovekraft  
Дата: 02.12.11 13:24
Оценка:
Здравствуйте, Obukhov, Вы писали:

O>DataContext один на всех, обслуживают 2-3 потока.

ССЗБ.
Правильное использование DataContext: создали, записали/прочитали, выбросили. Шарить его между потоками — извращение.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.