最近在測試關於 LiteDB 的各種可能 ,在之前的案例預設的時候, 你在操作 LiteDB 都是獨占式開啟
但是我在使用 他的 GUI 工具的時候發現他在連線的時候有一個選項 就是 Shared

這時候我就好奇了,到底如果我用 Shared 開啟的時候,我使用 Parallel.For 做一個測試,就是我一直去 Upsert 去寫入一筆資料
看看到底狀況會如何?
案例說明 一開始我一樣寫入 10萬筆資料,並且我用 Parallel.For 跑 100 讀取 id: friend99 並且在他的 Name 屬性後面加入 一個 ,index
這樣看看最後是不是答案是正確。
var sw = new Stopwatch();
// Create 10W data to test.
using (var db = new LiteDatabase(AppDomain.CurrentDomain.BaseDirectory + "sample.db"))
{
var userColleciton = db.GetCollection("FRIENDS");
for (var i = 1; i <= 100; i++)
{
var u = new Friend { _id = "friend" + i, CreateDate = DateTime.Now, IsActive = true, Name = "FRIEND" + i, Salary = i };
u.Phones.Add(new Friend.Phone { Num = "09" + i, Type = "HOME" });
userColleciton.Upsert(u);
}
}
sw.Start();
Parallel.For(1, 101,
index =>
{
//每一個迴圈都是用 Shared 的方式開啟 DB
//主要測試多線程下寫入一筆資料會不會產生 rollback
using (var db2 = new LiteDatabase(new ConnectionString { Connection = ConnectionType.Shared, Filename = AppDomain.CurrentDomain.BaseDirectory + "sample.db" }))
{
try
{
bool transactionCreated = db2.BeginTrans();
var friendColl = db2.GetCollection("FRIENDS");
//讀取id 微 friend99 這筆資料
var u = friendColl.FindById("friend99");
u.Name += ","+index;
friendColl.Upsert(u);
//call commit
db2.Commit();
Console.WriteLine("Success:" + index);
}
catch (Exception ex)
{
Console.WriteLine("Rollback:" + index);
db2.Rollback();
}
finally
{
db2.Dispose();
}
}
});
Console.WriteLine(sw.Elapsed.ToString());
Result:
{
"_id": "friend99",
"Name": "FRIEND99,7,25,61,67,43,37,1,55,49,31,13,19,73,79,85,91,97,8,26,62,68,44,38,2,3,56,50,32,14,20,74,80,86,92,98,9,27,63,69,45,39,5,10,4,57,51,33,15,21,75,81,87,93,99,11,28,64,70,46,40,6,16,18,22,58,52,34,76,82,88,94,100,12,29,65,71,47,41,17,23,59,53,35,77,83,89,95,30,66,72,48,42,24,60,54,36,78,84,90,96",
"CreateDate": {"$date": "2024-01-30T03:59:23.6020000Z"},
"Phones":
[
{
"Num": "0999",
"Type": "HOME"
}
],
"IsActive": true,
"Salary": {"$numberDecimal": "99"}
}

看起來式沒甚麼問題,這樣測試是比較暴力一點,這樣如果不會錯應該就足以應付很多日常狀況了