2012-06-25 2 views
5

Я просто проверить PetaPoco сделку в многопоточном пути ...PetaPoco сделка в многопоточном Env

У меня есть простой тест:

- Простое значение объект называют его MediaDevice - вставить записать обновить его в 1000 раз

void TransactionThread(Object object) 
{ 


    Database db = (Database) object; 

    for(int i= 0; i < 1000;i++) 
    { 


     Transaction transaction = db.GetTransaction(); 

     MediaDevice device = new MediaDevice(); 
     device.Name = "Name"; 
     device.Brand = "Brand"; 

     db.Insert(device); 

     device.Name = "Name_Updated"; 
     device.Brand = "Brand_Updated"; 


     db.Update(device); 

     transaction.Complete(); 

    } 


    long count = db.ExecuteScalar<long>("SELECT Count(*) FROM MediaDevices"); 

    Console.WriteLine("Number of all records:" + count); 

} 

И я называю это двумя нитями, как это: [Один объект базы данных для обоих потоков]

void TransactionTest() 
{ 

    Database db = GetDatabase(); 

    Thread tThread1 = ... // thread for TransactionTest() 

    Thread tThread2 = ... // thread for TransactionTest() 

    tThread1.Start(db); // pass Database to TransactionTest() 
    tThread2.Start(db); // pass same Database to TransactionTest() 

} 

я получаю ошибку Null или иногда объект, расположенную ошибки для базы данных ..

Но когда я поставить два экземпляра базы данных,

void TransactionTest() 
{ 

    Database db = GetDatabase(); 
    Database db2 = GetDatabase(); 

    Thread tThread1 = ... // thread for TransactionTest() 

    Thread tThread2 = ... // thread for TransactionTest() 


    tThread1.Start(db); // pass Database instance db to TransactionTest() 
    tThread2.Start(db2); // pass Database intance db2 to TransactionTest() 

} 

Everthing в порядке ...

Ну Когда я проверяю PetaPoco Исходный код по сделке. Я вижу, что по сделке. Завершено

public virtual void Complete() 
     { 
      _db.CompleteTransaction(); 
      _db = null; 
     } 

Мой вопрос заключается в возможности использовать транзакцию из нескольких потоков. Должен ли я использовать новую копию объекта базы данных? Или что я делаю неправильно?

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

ответ

1

Привет, используйте nolock в запросе select, потому что таблица может быть заблокирована. long count = db.ExecuteScalar («SELECT Count (*) с nolock FROM MediaDevices»);

+0

У меня не получалось исключений в этом выражении ... db.ExecuteScalar (...) – Novalis

1

извините, чувак .. да, вы правы. они меняют объект на нуль. поэтому вы не можете использовать один и тот же объект для потоковой обработки. вы должны использовать их, описанные как db = GetDataBase(); db2 = GetDataBase();

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

4

Да, для каждой нити требуется отдельный экземпляр базы данных PetaPoco. Смотрите эту цитату из документации PetaPoco:

Примечание: для сделок на работу, все операции должны использовать один и тот же экземпляр объекта базы данных PetaPoco. Таким образом, вы, вероятно, захотите, чтобы использовали для каждого HTTP-запроса, или для контейнера IOC для каждой нити, чтобы обслуживать общий экземпляр этого объекта. Лично StructureMap - это мой фаворит для этого.

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

Смежные вопросы