当业务有“要么都成功,要么都失败”的要求(如余额转账、库存扣减+订单创建),就必须使用事务。
TinyDb 的事务入口在 TinyDbEngine.BeginTransaction()。
1. 最小事务模板
using var db = new TinyDb.Core.TinyDbEngine("tx.db");
var users = db.GetCollection<User>();
var orders = db.GetCollection<Order>();
using var tx = db.BeginTransaction();
try
{
users.Insert(new User { Name = "新用户", Email = "new@example.com", Age = 20 });
orders.Insert(new Order { OrderNumber = "ORD-001", TotalAmount = 99.9m });
tx.Commit();
}
catch
{
tx.Rollback();
throw;
}2. 转账场景(推荐写法)
[Entity("accounts")]
public partial class Account
{
[Id]
public ObjectId Id { get; set; } = ObjectId.NewObjectId();
[Index(Unique = true)]
public string AccountNo { get; set; } = string.Empty;
public decimal Balance { get; set; }
}
public static bool Transfer(
TinyDb.Core.TinyDbEngine db,
ObjectId fromId,
ObjectId toId,
decimal amount)
{
var accounts = db.GetCollection<Account>();
using var tx = db.BeginTransaction();
try
{
var from = accounts.FindById(fromId);
var to = accounts.FindById(toId);
if (from == null || to == null) return false;
if (from.Balance < amount) return false;
from.Balance -= amount;
to.Balance += amount;
accounts.Update(from);
accounts.Update(to);
tx.Commit();
return true;
}
catch
{
tx.Rollback();
throw;
}
}3. 保存点(Savepoint)
保存点适合“一个大事务里有可回滚子步骤”的场景。
using var tx = db.BeginTransaction();
// 步骤 1:写入基础数据
step1();
var sp1 = tx.CreateSavepoint("after-step1");
// 步骤 2:写入扩展数据
step2();
// 步骤 3:高风险步骤
try
{
step3();
}
catch
{
// 只回滚到步骤1后的状态,保留 step1
tx.RollbackToSavepoint(sp1);
}
tx.Commit();4. 常见误区
误区:忘记
Commit()。说明:
using结束时,活动事务会走回滚路径。误区:在事务中做大量慢 I/O(HTTP、文件、外部 RPC)。
说明:会延长持锁时间,增加冲突与超时概率。应把外部 I/O 放到事务外。
误区:把“查询”与“写入”跨越很长时间。
说明:业务判断可能过期。应尽量缩短“读-改-写”窗口。
5. 事务配置建议
TinyDbOptions 中与事务相关的关键项:
var options = new TinyDb.Core.TinyDbOptions
{
MaxTransactions = 100,
TransactionTimeout = TimeSpan.FromMinutes(5),
WriteConcern = TinyDb.Core.WriteConcern.Synced
};MaxTransactions:限制并发事务数量。TransactionTimeout:限制事务生存时间。WriteConcern:提交时的持久化强度(详见进阶性能篇)。
6. 失败补偿与幂等建议
对于支付、库存等高价值场景,建议同时做:
业务幂等键(如
RequestId)。事务内唯一约束(防重复写)。
失败日志记录(便于追偿/重试)。
7. 小结
事务解决一致性,保存点解决“局部回滚”。
尽量缩短事务窗口,避免在事务中做慢操作。
高价值业务配合幂等设计,而不是只依赖事务。
下一篇进入并发常见需求:异步 API 与取消令牌。
发表评论