6

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

}

そして、私はこれを次のように2つのスレッドで呼び出します。[両方のスレッドの単一のデータベースオブジェクト]

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エラーまたはオブジェクト廃棄エラーが発生することがあります。

しかし、2つのデータベースインスタンスを提供すると、

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

}

すべてがOKです...

トランザクションでPetaPocoのソースコードを確認すると、トランザクションでそれがわかります。

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

私の質問は、複数のスレッドからのトランザクションを使用できるようにするために、データベースオブジェクトの新しいコピーを使用する必要があるかどうかです。または私は何が間違っているのですか?

そして、スレッドセーフにするために、データの更新クエリごとに新しいデータベースを開いたり閉じたりする必要がありますか?

4

3 に答える 3

4

はい、スレッドごとに別の PetaPoco データベース インスタンスが必要です。PetaPoco ドキュメントからのこの引用を参照してください。

注: トランザクションが機能するには、すべての操作で PetaPoco データベース オブジェクトの同じインスタンスを使用する必要があります。したがって、このオブジェクトの共有インスタンスを提供するために、http 要求ごと、またはスレッドごとの IOC コンテナーを使用することをお勧めします。個人的には StructureMap がお気に入りです。

手がかりを与えるフレーズを太字にしました。これは、PetaPoco データベース オブジェクトの 1 つのインスタンスをスレッドごとに使用する必要があることを示しています。

于 2012-09-28T18:48:22.527 に答える
1

テーブルがロックされている可能性があるため、選択クエリで nolock を使用します。long count = db.ExecuteScalar("SELECT Count(*) with nolock FROM MediaDevices");

于 2012-06-26T06:10:01.873 に答える
1

ごめんね..はい、あなたは正しいです。オブジェクトを null に変更します。そのため、同じオブジェクトをスレッドに使用することはできません。db=GetDataBase() のように記述して使用する必要があります。db2=GetDataBase();

それ以外の場合は、要件に合わせてソース コードを変更できます。彼らのライセンスはそれを許可していると思います。しかし、よくわかりません。

于 2012-06-26T10:22:16.863 に答える