Sqlsugar事务简单用法
1.配置UnitOfWork
// 定义一个名为 UnitOfWork 的公共类,并实现 IDisposable 接口
// IDisposable 接口用于释放非托管资源(在这里主要是数据库连接和事务)
public class UnitOfWork : IDisposable
{
// 1. 属性定义
// ILogger: 用于记录日志的接口,方便调试和追踪 UnitOfWork 的状态变化
public ILogger Logger { get; set; }
// ISqlSugarClient: SqlSugar ORM 的数据库客户端接口,用于执行数据库操作
public ISqlSugarClient Db { get; internal set; }
// ITenant: SqlSugar 的多租户接口,用于管理数据库事务
public ITenant Tenant { get; internal set; }
// IsTran: 布尔值,指示当前是否处于一个数据库事务中
public bool IsTran { get; internal set; }
// IsCommit: 布尔值,指示事务是否已经被提交
public bool IsCommit { get; internal set; }
// IsClose: 布尔值,指示数据库连接是否已经被关闭
public bool IsClose { get; internal set; }
// 2. Dispose 方法 (实现 IDisposable 接口)
// 当 UnitOfWork 对象被释放时(例如,使用 using 语句块结束时),会自动调用此方法
public void Dispose()
{
// a. 检查是否需要回滚事务
// 如果当前处于事务中 (IsTran 为 true) 但事务尚未提交 (IsCommit 为 false)
if (IsTran && !IsCommit)
{
// 记录调试日志,表明将要回滚事务
Logger.LogDebug("UnitOfWork RollbackTran");
// 调用 Tenant 的 RollbackTran 方法来回滚事务,撤销所有未提交的更改
Tenant.RollbackTran();
}
// b. 检查是否需要关闭数据库连接
// 如果数据库连接上仍有未完成的事务 或者 连接已经被标记为关闭
if (Db.Ado.Transaction != null || IsClose)
// 则不执行关闭操作,直接返回
return;
// 如果没有未完成的事务且连接未被标记关闭,则关闭数据库连接
Db.Close();
}
// 3. Commit 方法
// 用于显式提交事务
public bool Commit()
{
// a. 检查并提交事务
// 如果当前处于事务中 (IsTran 为 true) 但事务尚未提交 (IsCommit 为 false)
if (IsTran && !IsCommit)
{
// 记录调试日志,表明将要提交事务
Logger.LogDebug("UnitOfWork CommitTran");
// 调用 Tenant 的 CommitTran 方法来提交事务,将所有更改持久化到数据库
Tenant.CommitTran();
// 将 IsCommit 标记为 true,表示事务已提交
IsCommit = true;
}
// b. 检查并关闭数据库连接
// 如果数据库连接上没有未完成的事务 且 连接尚未被标记为关闭
if (Db.Ado.Transaction == null && !IsClose)
{
// 关闭数据库连接
Db.Close();
// 将 IsClose 标记为 true,表示连接已关闭
IsClose = true;
}
// 返回事务是否已提交的状态
return IsCommit;
}
}
2.配置IUnitOfWorkManage
public interface IUnitOfWorkManage
{
SqlSugarScope GetDbClient();
void BeginTran();
void CommitTran();
void RollbackTran();
UnitOfWork CreateUnitOfWork();
}
3.配置UnitOfWorkManage 实现IUnitOfWorkManage
// 定义一个公共类 UnitOfWorkManage,它实现了 IUnitOfWorkManage 接口
public class UnitOfWorkManage : IUnitOfWorkManage
{
// 1. 私有只读字段
// _logger: 用于记录日志,类型为 ILogger<UnitOfWorkManage>,表示这是专门给 UnitOfWorkManage 类使用的日志记录器
private readonly ILogger<UnitOfWorkManage> _logger;
// _sqlSugarClient: 注入的 SqlSugar 数据库客户端接口,用于执行数据库操作
private readonly ISqlSugarClient _sqlSugarClient;
// TranStack: 一个线程安全的栈,用于存储事务相关的标识符(例如事务ID)
// 这可能用于更复杂的嵌套事务或事务跟踪场景
public readonly ConcurrentStack<string> TranStack = new();
// 2. 构造函数
// 通过依赖注入获取所需的 ISqlSugarClient 和 ILogger 实例
public UnitOfWorkManage(ISqlSugarClient sqlSugarClient, ILogger<UnitOfWorkManage> logger)
{
_sqlSugarClient = sqlSugarClient;
_logger = logger;
}
/// <summary>
/// 获取DB,保证唯一性
/// </summary>
/// <returns></returns>
// 3. 获取数据库客户端实例的方法
public SqlSugarScope GetDbClient()
{
// 将注入的 _sqlSugarClient 强制转换为 SqlSugarScope 类型并返回
// 注释提示这很重要,因为后续可能需要使用 SqlSugarScope 特有的功能(如切换数据库)
// 假设注入的 _sqlSugarClient 实际上就是 SqlSugarScope 的实例
return _sqlSugarClient as SqlSugarScope;
}
// 4. 开始事务的方法
public void BeginTran()
{
// 使用 lock 关键字确保在同一时间只有一个线程可以执行此代码块
// 这是为了保证事务操作的线程安全
lock (this)
{
// 调用 GetDbClient() 获取 SqlSugarScope 实例,然后调用其 BeginTran() 方法开始一个新事务
GetDbClient().BeginTran();
}
}
// 5. 提交事务的方法
public void CommitTran()
{
// 同样使用 lock 确保线程安全
lock (this)
{
// 调用 GetDbClient() 获取 SqlSugarScope 实例,然后调用其 CommitTran() 方法提交当前事务
GetDbClient().CommitTran();
}
}
// 6. 回滚事务的方法
public void RollbackTran()
{
// 同样使用 lock 确保线程安全
lock (this)
{
// 调用 GetDbClient() 获取 SqlSugarScope 实例,然后调用其 RollbackTran() 方法回滚当前事务
GetDbClient().RollbackTran();
}
}
// 7. 创建 UnitOfWork 实例的方法
public UnitOfWork CreateUnitOfWork()
{
// a. 创建一个新的 UnitOfWork 对象
UnitOfWork uow = new()
{
// 将注入的 logger 赋值给 UnitOfWork 的 Logger 属性
Logger = _logger,
// 将注入的数据库客户端赋值给 UnitOfWork 的 Db 属性
Db = _sqlSugarClient,
// 将数据库客户端强制转换为 ITenant 接口并赋值给 UnitOfWork 的 Tenant 属性
// ITenant 接口通常包含事务管理方法 (BeginTran, CommitTran, RollbackTran)
Tenant = (ITenant)_sqlSugarClient,
// 将 IsTran 属性设置为 true,表示这个 UnitOfWork 关联的操作将在事务中进行
IsTran = true
};
// b. 打开数据库连接
uow.Db.Open();
// c. 通过 Tenant 接口开始一个事务
uow.Tenant.BeginTran();
// d. 记录调试日志,表明一个新的 UnitOfWork 已经开始
_logger.LogDebug("UnitOfWork Begin");
// e. 返回创建好的 UnitOfWork 实例
return uow;
}
}
4.在AutofacModuleRegister注册IUnitOfWorkManage及其实现类的服务

// 注册sqlsugar事务服务
builder.RegisterType(typeof(UnitOfWorkManage)).As(typeof(IUnitOfWorkManage)).InstancePerDependency();
5.在IBaseRepository及其实现类BaseRepository添加方法

/// <summary>
/// 添加一个
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<long> Add(TEntity entity);

public async Task<long> Add(TEntity entity)
{
var insert = _dbBaset.Insertable(entity);
return await insert.ExecuteReturnSnowflakeIdAsync();
}
6.在IBaseService及其实现类BaseService添加方法

/// <summary>
/// 添加一个
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<long> Add(TEntity entity);

public async Task<long> Add(TEntity entity)
{
return await _baseRepository.Add(entity);
}
7.创建控制器TransactionController
[Route("api/[controller]/[action]")]
[ApiController]
public class TransactionController : ControllerBase
{
private readonly IBaseService<Role, RoleVo> _roleService;
private readonly IUnitOfWorkManage _unitOfWorkManage;
public TransactionController(IBaseService<Role, RoleVo> roleService, IUnitOfWorkManage unitOfWorkManage)
{
_roleService = roleService;
_unitOfWorkManage = unitOfWorkManage;
}
[HttpGet]
public async Task<object> Get()
{
try
{
Console.WriteLine($"Begin Transaction");
//_unitOfWorkManage.BeginTran();
using var uow = _unitOfWorkManage.CreateUnitOfWork();
var roles = await _roleService.Query();
Console.WriteLine($"1 first time : the count of role is :{roles.Count}");
Console.WriteLine($"insert a data into the table role now.");
TimeSpan timeSpan = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var insertPassword = await _roleService.Add(new Role()
{
Id = timeSpan.TotalSeconds.ObjToLong(),
IsDeleted = false,
Name = "role name",
});
var roles2 = await _roleService.Query();
Console.WriteLine($"2 second time : the count of role is :{roles2.Count}");
int ex = 0;
Console.WriteLine($"There's an exception!!");
Console.WriteLine($" ");
int throwEx = 1 / ex;
uow.Commit();
//_unitOfWorkManage.CommitTran();
}
catch (Exception)
{
//_unitOfWorkManage.RollbackTran();
var roles3 = await _roleService.Query();
Console.WriteLine($"3 third time : the count of role is :{roles3.Count}");
}
return "ok";
}
}


浙公网安备 33010602011771号