2012-06-25 32 views
5

我只是测试PetaPoco事务在多线程的方式...PetaPoco交易在多线程信封

我有一个简单的测试案例:

- 简单的值对象称之为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() 

} 

我得到空错误或有时对象数据库配置错误..

但是当我提供两个数据库实例,

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() 

} 

寄托都正常...

那么当我检查PetaPoco交易处的源代码I在交易处看到。完成

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

我的问题是,能够使用来自多个线程的事务我是否必须使用数据库对象的新副本?或者我做错了什么?

为了使线程安全,我必须在每次数据更新查询时打开和关闭NEW数据库吗?

回答

1

在选择查询中使用nolock,因为表可能被锁定。 long count = db.ExecuteScalar(“SELECT Count(*)with nolock FROM MediaDevices”);

+0

我没有在此状态下得到异常... db.ExecuteScalar(...) – Novalis

1

对不起,你是对的。他们将对象更改为null。所以你不能使用相同的对象进行线程化。你必须使用它们描述的类似db = GetDataBase(); DB2 = GetDataBase();

否则,您可以更改您的需求的源代码。我认为他们的许可证允许。但我不确定。

4

是的,你需要一个单独的PetaPoco数据库实例。从PetaPoco文档见这句话:

注:交易工作,所有的操作都需要使用PetaPoco数据库对象的同一 实例。所以你可能想要 使用per-http请求,或者每个线程的IOC容器使用来为这个对象提供一个 共享实例。个人StructureMap是我最喜欢的 。

我粗体显示了提供线索的短语。这是说每个线程应该使用PetaPoco数据库对象的一个​​实例。