namespace CloudGaming.Core.EntityFramework.Aop;
///
/// 事务拦截
///
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class TransactionalAttribute : AopMoAttribute
{
///
/// 指定 数据上下文
///
private readonly Type[] _dbContextTypes;
///
/// 是否延迟提交
///
public bool IsCommitDelay { get; set; } = false;
public TransactionalAttribute()
{
_dbContextTypes = RepositoryEntityFrameworkExtensions.GetDbContextTypeAll().ToArray();
if (_dbContextTypes == null || _dbContextTypes.Length == 0)
{
throw new Exception(
"请在程序启动前注册 程序中所有的 dbContext 类型。例如: services.AddEntityFrameworkRepositories(typeof(AdminDbContext));");
}
}
///
/// 事务拦截
///
/// 数据上下文
public TransactionalAttribute(params Type[] dbContextTypes)
{
_dbContextTypes = dbContextTypes;
if (_dbContextTypes == null || _dbContextTypes.Length == 0)
{
throw new Exception(
"请在程序启动前注册 程序中所有的 dbContext 类型。例如: services.AddEntityFrameworkRepositories(typeof(AdminDbContext));");
}
}
///
///
///
///
public override void OnEntry(MethodContext context)
{
foreach (var dbContextType in _dbContextTypes)
{
if (IsCommitDelay)
{
// 延迟提交
var baseDbContext = GetService(context, dbContextType) as IBaseDbContext;
baseDbContext?.UnitOfWork?.CommitDelayStart();
}
else
{
var dbContext = GetService(context, dbContextType) as DbContext;
dbContext?.Database.OpenConnection();
dbContext?.Database.BeginTransaction();
}
}
}
public override void OnException(MethodContext context)
{
if (!IsCommitDelay)
{
//函数异常触发事件
foreach (var dbContextType in _dbContextTypes)
{
var dbContext = GetService(context, dbContextType) as DbContext;
if (dbContext?.Database.CurrentTransaction != null)
{
dbContext.Database.RollbackTransaction();
}
}
}
// 获取日志对象
var logger = GetLogger(context);
logger?.LogError(context.Exception, "事务异常");
}
public override void OnSuccess(MethodContext context)
{
foreach (var dbContextType in _dbContextTypes)
{
if (IsCommitDelay)
{
// 延迟提交
var baseDbContext = GetService(context, dbContextType) as IBaseDbContext;
baseDbContext?.UnitOfWork?.CommitDelayEnd();
}
else
{
var dbContext = GetService(context, dbContextType) as DbContext;
dbContext?.Database.CommitTransaction();
}
}
}
public override void OnExit(MethodContext context)
{
base.OnExit(context);
}
}