在现代软件开发中,数据的可靠性和一致性至关重要。每一个数据库操作都潜藏着风险:一个意外的系统崩溃、一个未处理的异常,都可能导致数据的部分损坏或完全丢失。这就是为什么事务管理成为数据库设计中最关键的特性之一。
对于追求轻量级、高效率的开发者来说,LiteDB 是一个令人兴奋的选择。它不仅提供了简单直观的 API,还内置了强大的事务管理机制。本文将深入探索 LiteDB 的事务世界,揭示如何通过精妙的事务控制,为您的应用程序构建坚不可摧的数据保护屏障。
无论您是一名经验丰富的开发者,还是刚开始接触数据库编程的新手,这篇文章都将为您呈现 LiteDB 事务管理的方方面面:从基本的 ACID 特性,到复杂的事务处理模式,我们将带您穿越数据一致性的迷雾,直达技术的璀璨之巅。
事务的ACID特性
事务(Transaction)是数据库管理系统中确保数据一致性和完整性的关键机制。在 LiteDB 中,事务遵循经典的 ACID 特性:
A - 原子性(Atomicity)
- 事务中的所有操作要么全部成功,要么全部回滚
- 保证了数据操作的不可分割性
C - 一致性(Consistency)
- 事务执行前后,数据库的状态必须保持一致
- 防止事务导致数据库处于不合法的状态
I - 隔离性(Isolation)
- 并发执行的事务相互隔离,互不影响
- 防止多个事务同时操作同一数据时产生冲突
D - 持久性(Durability)
- 事务一旦提交,其修改将永久保存
- 即使系统发生故障,已提交的事务不会丢失
LiteDB 显式事务管理
Nuget 安装LiteDB

基本显式事务示例
// 用户实体类
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}复制
using LiteDB;
namespace App12
{
internal class Program
{
static void Main(string[] args)
{
PerformExplicitTransaction();
}
public static void PerformExplicitTransaction()
{
// 使用数据库连接字符串创建数据库实例
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
try
{
// 开始显式事务
db.BeginTrans();
// 获取用户集合
var users = db.GetCollection<User>("users");
// 执行多个操作
var newUser = new User
{
Name = "张三",
Age = 30
};
users.Insert(newUser);
// 更新另一个用户
var existingUser = users.FindOne(u => u.Name == "李四");
if (existingUser != null)
{
existingUser.Age += 1;
users.Update(existingUser);
}
// 提交事务
db.Commit();
Console.WriteLine("事务成功提交");
}
catch (Exception ex)
{
// 发生异常时回滚事务
db.Rollback();
Console.WriteLine($"事务回滚:{ex.Message}");
}
}
}
}
}复制


事务回滚场景
using LiteDB;
namespace App12
{
// 定义银行账户类
publicclass BankAccount
{
public ObjectId Id { get; set; }
publicstring AccountNumber { get; set; }
public decimal Balance { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 先初始化数据
InitializeDatabase();
Console.WriteLine("转账演示开始...");
Console.WriteLine("-------------------");
// 显示初始余额
DisplayAllAccounts();
// 执行转账操作
TransactionRollbackDemo();
// 显示转账后的余额
Console.WriteLine("\n转账后的账户余额:");
DisplayAllAccounts();
}
// 初始化数据库
public static void InitializeDatabase()
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
var accounts = db.GetCollection<BankAccount>("accounts");
// 清空已有数据
accounts.DeleteAll();
// 插入初始账户
accounts.Insert(new BankAccount { AccountNumber = "1001", Balance = 1000 });
accounts.Insert(new BankAccount { AccountNumber = "1002", Balance = 1000 });
Console.WriteLine("数据库初始化完成");
}
}
// 显示所有账户余额
public static void DisplayAllAccounts()
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
var accounts = db.GetCollection<BankAccount>("accounts");
var allAccounts = accounts.FindAll();
Console.WriteLine("\n当前所有账户余额:");
foreach (var account in allAccounts)
{
Console.WriteLine($"账户 {account.AccountNumber}: {account.Balance:C}");
}
}
}
public static void TransactionRollbackDemo()
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
db.BeginTrans();
try
{
var accounts = db.GetCollection<BankAccount>("accounts");
// 模拟银行转账
var fromAccount = accounts.FindOne(a => a.AccountNumber == "1001");
var toAccount = accounts.FindOne(a => a.AccountNumber == "1002");
decimal transferAmount = 1500; // 转账金额大于余额,将触发异常
Console.WriteLine($"\n尝试从账户 {fromAccount.AccountNumber} 转账 {transferAmount:C} 到账户 {toAccount.AccountNumber}");
// 检查余额是否充足
if (fromAccount.Balance < transferAmount)
{
// 余额不足,抛出异常触发回滚
thrownew InvalidOperationException("余额不足,无法转账");
}
// 扣除转出账户余额
fromAccount.Balance -= transferAmount;
accounts.Update(fromAccount);
// 增加转入账户余额
toAccount.Balance += transferAmount;
accounts.Update(toAccount);
// 提交事务
db.Commit();
Console.WriteLine("转账成功");
}
catch (Exception ex)
{
// 发生异常,回滚所有操作
db.Rollback();
Console.WriteLine($"转账失败:{ex.Message}");
}
}
}
}
}复制

LiteDB 隐式事务应用
单一操作的隐式事务
LiteDB 对于单个操作(如插入、更新、删除)会自动管理事务:
using LiteDB;
namespace App12
{
publicclass Product
{
public ObjectId Id { get; set; } // 使用 LiteDB 的 ObjectId 作为主键
publicstring Name { get; set; }
public decimal Price { get; set; }
publicint Stock { get; set; } // 添加库存字段
public DateTime CreatedDate { get; set; }
}
internal class Program
{
static void Main(string[] args)
{
// 初始化产品数据
InitializeProducts();
Console.WriteLine("初始产品列表:");
DisplayAllProducts();
// 测试隐式事务
ImplicitTransactionDemo();
Console.WriteLine("\n操作后的产品列表:");
DisplayAllProducts();
}
public static void InitializeProducts()
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
var products = db.GetCollection<Product>("products");
// 清空现有数据
products.DeleteAll();
// 插入初始产品数据
products.Insert(new Product
{
Name = "智能手机",
Price = 3999.99m,
Stock = 50,
CreatedDate = DateTime.Now
});
products.Insert(new Product
{
Name = "平板电脑",
Price = 4599.99m,
Stock = 30,
CreatedDate = DateTime.Now
});
// 创建索引
products.EnsureIndex(x => x.Name);
Console.WriteLine("产品数据初始化完成");
}
}
public static void DisplayAllProducts()
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
var products = db.GetCollection<Product>("products");
var allProducts = products.FindAll();
Console.WriteLine("\n产品列表:");
Console.WriteLine("----------------------------------------");
Console.WriteLine("名称\t\t价格\t\t库存\t创建时间");
Console.WriteLine("----------------------------------------");
foreach (var product in allProducts)
{
Console.WriteLine($"{product.Name,-16}{product.Price,10:C}{product.Stock,8}\t{product.CreatedDate:yyyy-MM-dd}");
}
Console.WriteLine("----------------------------------------");
}
}
public static void ImplicitTransactionDemo()
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
var products = db.GetCollection<Product>("products");
try
{
// 1. 插入新产品(单一操作,LiteDB 自动管理事务)
var newProduct = new Product
{
Name = "笔记本电脑",
Price = 5999.99m,
Stock = 20,
CreatedDate = DateTime.Now
};
products.Insert(newProduct);
Console.WriteLine("\n新产品添加成功:" + newProduct.Name);
// 2. 更新现有产品价格(原子操作)
var existingProduct = products.FindOne(p => p.Name == "智能手机");
if (existingProduct != null)
{
decimal oldPrice = existingProduct.Price;
existingProduct.Price -= 500;
products.Update(existingProduct);
Console.WriteLine($"\n产品'{existingProduct.Name}'价格更新成功:");
Console.WriteLine($"原价:{oldPrice:C} -> 新价:{existingProduct.Price:C}");
}
// 3. 补充库存(原子操作)
var tabletProduct = products.FindOne(p => p.Name == "平板电脑");
if (tabletProduct != null)
{
int oldStock = tabletProduct.Stock;
tabletProduct.Stock += 10;
products.Update(tabletProduct);
Console.WriteLine($"\n产品'{tabletProduct.Name}'库存更新成功:");
Console.WriteLine($"原库存:{oldStock} -> 新库存:{tabletProduct.Stock}");
}
// 4. 删除过期产品(如果存在)
var result = products.DeleteMany(p => p.CreatedDate < DateTime.Now.AddYears(-1));
if (result > 0)
{
Console.WriteLine($"\n删除了 {result} 个过期产品");
}
}
catch (Exception ex)
{
Console.WriteLine($"\n操作出错:{ex.Message}");
}
}
}
// 添加一个辅助方法来搜索产品
public static void SearchProducts(string keyword)
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
var products = db.GetCollection<Product>("products");
var searchResults = products.Find(p => p.Name.Contains(keyword));
Console.WriteLine($"\n搜索结果 (关键词: {keyword}):");
Console.WriteLine("----------------------------------------");
foreach (var product in searchResults)
{
Console.WriteLine($"{product.Name} - {product.Price:C} - 库存:{product.Stock}");
}
Console.WriteLine("----------------------------------------");
}
}
}
}复制

批量操作的隐式事务
对于批量操作,建议使用显式事务以获得更好的性能和控制:
using LiteDB;
using System;
using System.Collections.Generic;
using System.Linq;
namespace App12
{
publicclass Order
{
public ObjectId Id { get; set; }
publicstring OrderNumber { get; set; }
public DateTime OrderDate { get; set; }
public decimal TotalAmount { get; set; }
publicstring CustomerName { get; set; }
publicstring Status { get; set; } // 订单状态:Pending, Completed, Cancelled
public List<OrderItem> Items { get; set; }
}
publicclass OrderItem
{
publicstring ProductName { get; set; }
publicint Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal Subtotal => Quantity * UnitPrice;
}
internal class Program
{
static void Main(string[] args)
{
var program = new Program();
Console.WriteLine("开始批量订单操作演示...");
program.BatchOperationDemo();
Console.WriteLine("\n订单统计信息:");
program.DisplayOrderStatistics();
}
public void BatchOperationDemo()
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
var orders = db.GetCollection<Order>("orders");
// 清空现有订单
orders.DeleteAll();
// 创建索引
orders.EnsureIndex(x => x.OrderNumber, unique: true);
orders.EnsureIndex(x => x.OrderDate);
orders.EnsureIndex(x => x.CustomerName);
// 使用显式事务处理批量操作
try
{
db.BeginTrans();
Console.WriteLine("开始生成订单...");
// 批量插入订单
var newOrders = GenerateOrders(100);
orders.InsertBulk(newOrders);
// 模拟一些额外的操作
UpdateRandomOrderStatus(orders);
db.Commit();
Console.WriteLine($"成功插入 {newOrders.Count()} 个订单");
// 显示一些示例订单
DisplaySampleOrders(orders);
}
catch (Exception ex)
{
db.Rollback();
Console.WriteLine($"批量操作失败:{ex.Message}");
}
}
}
private IEnumerable<Order> GenerateOrders(int count)
{
var random = new Random();
var customers = new[] { "张三", "李四", "王五", "赵六", "钱七" };
var products = new[]
{
("笔记本电脑", 5999m),
("智能手机", 3999m),
("平板电脑", 2999m),
("智能手表", 1999m),
("蓝牙耳机", 999m)
};
for (int i = 0; i < count; i++)
{
var orderItems = new List<OrderItem>();
var itemCount = random.Next(1, 4); // 每个订单1-3个商品
for (int j = 0; j < itemCount; j++)
{
var product = products[random.Next(products.Length)];
orderItems.Add(new OrderItem
{
ProductName = product.Item1,
Quantity = random.Next(1, 4),
UnitPrice = product.Item2
});
}
var order = new Order
{
OrderNumber = $"ORD{DateTime.Now:yyyyMMdd}{i + 1:D4}",
OrderDate = DateTime.Now.AddDays(-random.Next(0, 30)),
CustomerName = customers[random.Next(customers.Length)],
Status = "Pending",
Items = orderItems,
TotalAmount = orderItems.Sum(item => item.Subtotal)
};
yield return order;
}
}
private void UpdateRandomOrderStatus(ILiteCollection<Order> orders)
{
var random = new Random();
var statuses = new[] { "Completed", "Cancelled" };
// 随机更新一些订单状态
var someOrders = orders.Find(Query.All(), limit: 20);
foreach (var order in someOrders)
{
if (random.Next(2) == 0) // 50% 的概率更新状态
{
order.Status = statuses[random.Next(statuses.Length)];
orders.Update(order);
}
}
}
private void DisplaySampleOrders(ILiteCollection<Order> orders)
{
Console.WriteLine("\n示例订单信息:");
Console.WriteLine("----------------------------------------");
var sampleOrders = orders.Find(Query.All(), limit: 5);
foreach (var order in sampleOrders)
{
Console.WriteLine($"订单号: {order.OrderNumber}");
Console.WriteLine($"客户: {order.CustomerName}");
Console.WriteLine($"日期: {order.OrderDate:yyyy-MM-dd}");
Console.WriteLine($"状态: {order.Status}");
Console.WriteLine("商品列表:");
foreach (var item in order.Items)
{
Console.WriteLine($" - {item.ProductName} x {item.Quantity} @ {item.UnitPrice:C} = {item.Subtotal:C}");
}
Console.WriteLine($"总金额: {order.TotalAmount:C}");
Console.WriteLine("----------------------------------------");
}
}
public void DisplayOrderStatistics()
{
using (var db = new LiteDatabase(@"MyDatabase.db"))
{
var orders = db.GetCollection<Order>("orders");
var totalOrders = orders.Count();
var totalAmount = orders.FindAll().Sum(o => o.TotalAmount);
var pendingOrders = orders.Count(Query.EQ("Status", "Pending"));
var completedOrders = orders.Count(Query.EQ("Status", "Completed"));
var cancelledOrders = orders.Count(Query.EQ("Status", "Cancelled"));
Console.WriteLine($"订单总数: {totalOrders}");
Console.WriteLine($"订单总金额: {totalAmount:C}");
Console.WriteLine($"待处理订单: {pendingOrders}");
Console.WriteLine($"已完成订单: {completedOrders}");
Console.WriteLine($"已取消订单: {cancelledOrders}");
// 按客户统计
var customerOrders = orders.FindAll()
.GroupBy(o => o.CustomerName)
.Select(g => new
{
Customer = g.Key,
OrderCount = g.Count(),
TotalAmount = g.Sum(o => o.TotalAmount)
})
.OrderByDescending(x => x.TotalAmount);
Console.WriteLine("\n客户订单统计:");
Console.WriteLine("----------------------------------------");
foreach (var stat in customerOrders)
{
Console.WriteLine($"客户: {stat.Customer}");
Console.WriteLine($"订单数: {stat.OrderCount}");
Console.WriteLine($"总金额: {stat.TotalAmount:C}");
Console.WriteLine("----------------------------------------");
}
}
}
}
}复制

5. 注意事项
- LiteDB 是一个轻量级的嵌入式数据库,事务管理相对简单
- 对于高并发场景,可能需要考虑更复杂的并发控制机制
- 始终关注异常处理和事务回滚逻辑
- 对于复杂的、多步骤的数据库操作,始终使用显式事务
- 尽可能缩小事务的作用范围,提高并发性能
- 捕获并处理可能的异常,确保事务能正确回滚
- 对于大批量数据操作,考虑分批处理以减少内存压力
结论
通过合理使用 LiteDB 的事务管理机制,可以确保数据的一致性和完整性,为应用程序提供可靠的数据持久化解决方案。
如果你正在从事上位机、自动化、机器视觉、物联网(IOT)项目或数字化转型方面的工作,欢迎加入我的微信圈子!在这里,我们不仅可以轻松畅聊最新技术动态和行业趋势,还能够在技术问题上互相帮助和支持。我会尽量利用我的知识和经验来帮助你解决问题,当然也期待从大家的专业见解中学习和成长。无论你是新手还是老鸟,期待与志同道合的朋友交流心得,一起进步!
文章转载自技术老小子,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。