首页 > 解决方案 > 如何防止使用 EF 并发执行 SQL Server 存储过程?

问题描述

我正在使用 Entity Framework 6 Database.SqlQuery 语句来执行存储过程。我想防止两个用户同时执行相同的存储过程。

标签: c#sqlsql-serverentity-framework

解决方案


此代码适用于同步和异步版本

    private static readonly SemaphoreLocker _semaphoreLocker = new SemaphoreLocker();
    public async Task<List<TResult>> ExecuteStoredProcedureWithLockAsync<TResult>(string storedProcedureName, object parameters, CancellationToken cancellationToken) where TResult : new()
    {
        List<TResult> result = new List<TResult>();
        await _semaphoreLocker.LockAsync(async () =>
        {
            result = await ExecuteStoredProcedureAsync<TResult>(storedProcedureName, parameters, cancellationToken);
        }, cancellationToken);
        return result;
    }
    private Object _locker = new Object();
    public List<TResult> ExecuteStoredProcedureWithLock<TResult>(string storedProcedureName, object parameters) where TResult : new()
    {
        lock (_locker)
        {
            return ExecuteStoredProcedure<TResult>(storedProcedureName, parameters);
        }
    }

private class SemaphoreLocker
{
    private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);

    public async Task LockAsync(Func<Task> worker, CancellationToken cancellationToken)
    {
        await _semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
        try
        {
            await worker();
        }
        finally
        {
            _semaphore.Release();
        }
    }
}

推荐阅读