using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace CloudBuilder.Core.DatabaseAccessor
{
    /*
        事务范围不匹配：TransactionScope 管理的是分布式事务，但对于单个数据库连接，通常不需要分布式事务。
        OnActionExecutionAsync 是 ASP.NET Core 中异步的 Action 过滤器执行方法。
        // OnActionExecuting: Action 执行前
        [开始事务]
        ↓
        [Action 方法执行]
        ↓
        // OnActionExecuted: Action 执行后（无论是否异常）
        [检查异常]
        [提交或回滚事务]
     */
    [AttributeUsage(AttributeTargets.Method)]
    public class UnitOfWorkAttribute : ActionFilterAttribute
    {
        private TransactionScope _transactionScope;

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            _transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew,
                new TransactionOptions
                {
                    IsolationLevel = IsolationLevel.ReadCommitted,
                    Timeout = TransactionManager.MaximumTimeout
                });

            base.OnActionExecuting(context);
        }

        public override void OnActionExecuted(ActionExecutedContext context)
        {
            if (_transactionScope != null)
            {
                if (context.Exception == null)
                {
                    //必须要有 SaveChanges() 调用，否则数据只会停留在内存中，不会真正保存到数据库。
                    _transactionScope.Complete();
                }
                _transactionScope.Dispose();
            }

            base.OnActionExecuted(context);
        }
    }
}
