using KH.WMS.Core.Database.Repositories;
using KH.WMS.Core.DependencyInjection.ServiceLifetimes;
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SqlSugar;
namespace KH.WMS.Core.Database.SqlSugar;
///
/// SQL Sugar 数据库上下文(支持事务嵌套)
///
[RegisteredService(Lifetime = Microsoft.Extensions.DependencyInjection.ServiceLifetime.Scoped)]
public class SqlSugarDbContext : IDbContext
{
private readonly ISqlSugarClient _sqlSugarClient;
private readonly ILogger _logger;
private readonly DatabaseOptions _options;
// 事务栈,用于支持嵌套事务
private readonly Stack _transactionScopes = new();
public SqlSugarDbContext(
ISqlSugarClient sqlSugarClient,
ILogger logger,
IOptions options)
{
_sqlSugarClient = sqlSugarClient;
_logger = logger;
_options = options.Value;
}
///
/// 获取当前事务隔离级别
///
public System.Data.IsolationLevel? CurrentIsolationLevel =>
_transactionScopes.Count > 0 ? _transactionScopes.Peek().IsolationLevel : null;
public ISqlSugarClient Db => _sqlSugarClient;
public async Task BeginTransactionAsync(System.Data.IsolationLevel isolationLevel = System.Data.IsolationLevel.ReadCommitted)
{
await _sqlSugarClient.Ado.BeginTranAsync(isolationLevel);
}
public async Task CommitTransactionAsync()
{
await _sqlSugarClient.Ado.CommitTranAsync();
_logger.LogInformation("事务已提交");
}
public async Task RollbackTransactionAsync()
{
await _sqlSugarClient.Ado.RollbackTranAsync();
_logger.LogInformation("事务已回滚");
}
public IRepository GetRepository() where T : class, new() where TKey : struct
{
return new RepositoryBase(_sqlSugarClient, _logger);
}
public void Dispose()
{
// 如果有未提交的事务,自动回滚
_sqlSugarClient?.Ado.RollbackTran();
_sqlSugarClient?.Dispose();
}
IRepository IDbContext.GetRepository()
{
throw new NotImplementedException();
}
///
/// 事务作用域
///
private class TransactionScope
{
public System.Data.IsolationLevel IsolationLevel { get; }
public bool IsCompleted { get; set; }
public bool RequiresRollback { get; set; }
public TransactionScope(System.Data.IsolationLevel isolationLevel)
{
IsolationLevel = isolationLevel;
IsCompleted = false;
RequiresRollback = false;
}
}
}