我只是以多线程方式测试PetaPoco Transaction ...
我有一个简单的测试用例:
- 简单值对象称之为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);
}
Run Code Online (Sandbox Code Playgroud)
我在这两个线程中调用它:[两个线程的单个数据库对象]
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()
}
Run Code Online (Sandbox Code Playgroud)
我得到Null错误或有时数据库的Object dispos错误..
但是当我提供两个数据库实例时,
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()
}
Run Code Online (Sandbox Code Playgroud)
Everthing还行......
那么当我在事务中检查PetaPoco源代码时,我会在transaction.Complete中看到它
public virtual void Complete()
{
_db.CompleteTransaction();
_db = null;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是能够使用来自多个线程的事务我是否必须使用Database对象的新副本?或者我做错了什么?
为了使其线程安全,我是否必须在每次数据更新查询时打开和关闭新数据库?
小智 1
您可以在 select 查询中使用 nolock,因为表可能被锁定。long count = db.ExecuteScalar("SELECT Count(*) with nolock FROM MediaDevices");