PetaPoco交易在多线程信封(PetaPoco Transaction in Multithre

2019-06-25 18:23发布

我只是测试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源代码,我看到,在transaction.Complete

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

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

并使其线程安全的我一定要打开,并在每个数据更新询问关闭新的数据库?

Answer 1:

是的,你需要每个线程独立PetaPoco数据库实例。 请参阅从PetaPoco文档这句话:

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

我加粗,使该线索的短语。 这是说,PetaPoco数据库对象的一个​​实例应该每个线程中使用。



Answer 2:

喜在选择查询使用NOLOCK使用,因为该表可能被锁定。 长计数= db.ExecuteScalar( “使用NOLOCK FROM MediaDevices SELECT COUNT(*)”);



Answer 3:

抱歉,伙计..是的,你是对的。 他们改变了对象为空。 所以你不能使用同一个对象的线程。 你必须使用他们使用像分贝= GetDataBase描述(); DB2 = GetDataBase();

否则,你可以更改源代码,您的要求。 我认为他们的执照允许它。 但我不知道。



文章来源: PetaPoco Transaction in Multithread Env
标签: petapoco