PetaPoco Transaction in Multithread Env
Asked Answered
K

3

6

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?

Kimsey answered 25/6, 2012 at 15:7 Comment(0)
F
4

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.

Follower answered 28/9, 2012 at 18:48 Comment(0)
L
1

Hi use with nolock in select query because the table may be locked. long count = db.ExecuteScalar("SELECT Count(*) with nolock FROM MediaDevices");

Lamella answered 26/6, 2012 at 6:10 Comment(1)
I did not get exceptions at this statementent...db.ExecuteScalar(...)Kimsey
L
1

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.

Lamella answered 26/6, 2012 at 10:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.