最近依然在測試 LiteDB,今天要測試的是 Transaction ,在 LiteDB 中 Transaction 其實很簡單的
跟傳統在寫 SQL Server 的 Transaction 設計的很像,我網路上查了一下文件,其實到 v5 之後版本寫法變得比較穩定
今天就簡單的記錄一下

範例描述,我會建立 10W 筆資料起來,之後我會跑一個 Parallel.For 然後執行 Upsert 寫入 _id : friend1 ~ friend100
的 Name 改成 --EDITED ,因為我測試其實很難發生錯誤,自己 throw 一個錯誤這樣測試很無聊
所以我改寫每一次跑,我故意都會讓他去碰撞 db 那顆檔案的存取權,錯誤就是無限的重新寫入到成功為止
//Create 10W data to test.
var sw = new Stopwatch();
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 =>
{
var isCommit = false;
LiteDatabase db2 = null;
while (!isCommit)
{
try
{
db2 = new LiteDatabase(AppDomain.CurrentDomain.BaseDirectory + "sample.db");
//begin transaction
bool transactionCreated = db2.BeginTrans();
var friendColl = db2.GetCollection("FRIENDS");
var u = new Friend { _id = "friend" + index, CreateDate = DateTime.Now, IsActive = true, Name = "FRIEND" + index + "--EDITED", Salary = index };
u.Phones.Add(new Friend.Phone { Num = "09" + index, Type = "HOME" });
friendColl.Upsert(u);
//call commit
db2.Commit();
isCommit = true;
Console.WriteLine("Success:" + index);
db2.Dispose();
}
catch (Exception ex)
{
Console.WriteLine("Rollback:" + index);
if (db2 != null)
{
//call rollback
db2.Rollback();
db2.Dispose();
}
}
}
});
Result:


這算是一個瘋狂測試驗證他的安全性但是其實就是很簡單的 BeginTrans => 動作 => Commit || Rollback