同步拦截的方法上面的文章也写清楚了,本文主要是写异步拦截
同步拦截:
public class TransactionInterceptor : IInterceptor
{
private readonly TransactionAsyncInterceptor _transactionAsyncInterceptor;
public TransactionInterceptor(TransactionAsyncInterceptor transactionAsyncInterceptor)
{
_transactionAsyncInterceptor = transactionAsyncInterceptor;
}
public void Intercept(IInvocation invocation)
{
_transactionAsyncInterceptor.ToInterceptor().Intercept(invocation);
}
}
异步拦截:
public class TransactionAsyncInterceptor : IAsyncInterceptor
{
public readonly SqlSugarTransaction _sqlSugarTransaction;
public TransactionAsyncInterceptor(SqlSugarTransaction sqlSugarTransaction)
{
_sqlSugarTransaction = sqlSugarTransaction;
}
private bool TryBegin(IInvocation invocation)
{
var method = invocation.MethodInvocationTarget ?? invocation.Method;
var attribute = method.GetCustomAttributes(typeof(TransactionAttribute), false).FirstOrDefault();
if (attribute is TransactionAttribute transaction)
{
_sqlSugarTransaction.BeginTran();
return true;
}
return false;
}
private async Task InternalInterceptAsynchronous(IInvocation invocation)
{
invocation.Proceed();
try
{
//处理Task返回一个null值的情况会导致空指针
if (invocation.ReturnValue != null)
{
await (Task)invocation.ReturnValue;
}
_sqlSugarTransaction.CommitTran();
}
catch (System.Exception)
{
_sqlSugarTransaction.RollbackTran();
throw;
}
}
private async Task<TResult> InternalInterceptAsynchronous<TResult>(IInvocation invocation)
{
TResult result;
if (TryBegin(invocation))
{
try
{
invocation.Proceed();
result = await (Task<TResult>)invocation.ReturnValue;
if (result is IResponseOutput res && !res.Success)
{
_sqlSugarTransaction.RollbackTran();
}
else
{
_sqlSugarTransaction.CommitTran();
}
}
catch (System.Exception)
{
_sqlSugarTransaction.RollbackTran();
throw;
}
}
else
{
invocation.Proceed();
result = await (Task<TResult>)invocation.ReturnValue;
}
return result;
}
/// <summary>
/// 拦截同步方法
/// </summary>
/// <param name="invocation"></param>
public void InterceptSynchronous(IInvocation invocation)
{
if (TryBegin(invocation))
{
try
{
invocation.Proceed();
var result = invocation.ReturnValue;
if (result is IResponseOutput res && !res.Success)
{
_sqlSugarTransaction.RollbackTran();
}
else
{
_sqlSugarTransaction.CommitTran();
}
}
catch
{
_sqlSugarTransaction.RollbackTran();
throw;
}
}
else
{
invocation.Proceed();
}
}
/// <summary>
/// 拦截返回结果为Task的方法
/// </summary>
/// <param name="invocation"></param>
public void InterceptAsynchronous(IInvocation invocation)
{
if (TryBegin(invocation))
{
invocation.ReturnValue = InternalInterceptAsynchronous(invocation);
}
else
{
invocation.Proceed();
}
}
/// <summary>
/// 拦截返回结果为Task<TResult>的方法
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="invocation"></param>
public void InterceptAsynchronous<TResult>(IInvocation invocation)
{
invocation.ReturnValue = InternalInterceptAsynchronous<TResult>(invocation);
}
}