Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PetaPoco Transaction in Multithread Env

Tags:

petapoco

I just test PetaPoco Transaction in a multithread way...

I have a simple test case :

-- Simple value object call it MediaDevice -- Insert a record an update it for 1000 times

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

}

And I call this in two threads like this:[ Single Database object for both threads]

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

}

I get Null error or sometimes Object disposed error for Database..

But when i supply two Database instance,

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 is OK...

Well When I check PetaPoco source code at transaction I see that at transaction.Complete

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

My question is that to able to use transaction from multiple threads Do I have to use new copy of Database object? Or what am i doing wrong?

And to make it thread safe do i have to open and close NEW database at every data update-query?

like image 552
Novalis Avatar asked Jun 25 '12 15:06

Novalis


Video Answer


2 Answers

Yes, you need a separate PetaPoco Database instance per-thread. See this quote from the PetaPoco documentation:

Note: for transactions to work, all operations need to use the same instance of the PetaPoco database object. So you'll probably want to use a per-http request, or per-thread IOC container to serve up a shared instance of this object. Personally StructureMap is my favourite for this.

I bolded the phrase that gives the clue. It is saying that one instance of the PetaPoco database object should be used per-thread.

like image 135
Jerome Avatar answered Oct 13 '22 03:10

Jerome


sorry dude.. yes you are right. they change the object to be null. so you cannot use the same object to threading. you have to use they use described like db=GetDataBase() ; db2=GetDataBase();

otherwise you can change the source code for your requirement. i think their license allow it. but i am not sure.

like image 35
surez Avatar answered Oct 13 '22 02:10

surez