Home Full Site
C# 동시 병렬 호출

데드락(Dead lock - 복수의 쓰레드가 상대가 소유한 리소스를 서로 기다리고 있는 상황)은 트래픽이 많은 Production 데이타베이스에서 가끔 발생하는 문제이다. SQL Server는 이러한 Dead Lock 상황이 발생하면 해당 쓰레드들 중 가장 트랜잭션이 짧게 진행된 쓰레드 (즉, BEGIN TRAN 이후 Transaction Log가 좀 더 적게 쌓인 쪽)를 자동적으로 종료하여 데드락 상황을 해소한다. 하지만 이러한 데드락이 자주 발생한다면, SQL 프로그래밍이 잘못된 경우가 대부분이므로 이를 수정해 줘야 한다. 문제는 상당한 경우 이러한 데드락은 스트레스가 적은 개인 머신이나 테스트 머신에서는 잘 발생하지 않는다는 것이다. 따라서 대량의 호출이 동시에 발생하는 Production 서버를 시물레이션하기 위해 스트레스용 프로그램을 작성해야 하는 경우가 종종 있다. (물론 외부 툴을 사용할 수 있지만) 아래는 C#에서 Parallel 클래스를 이용하여 간단하게 SQL Server의 Stored Procedure를 동시에 100개 쓰레드를 만들어 호출하는 예제이다.

예제

using System;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace NS
{
    class Program
    {
        static void Main(string[] args)
        {
            // 동시에 100개 쓰레드를 만들어 병렬 실행
            // CPU Core 갯수에 따라 자동 병렬 처리
            Parallel.For(0, 100, (i) => Run(i));
        }

        static void Run(int i)
        {
            var strConn = "Data Source=Test1;Initial Catalog=DB1;Integrated Security=true";

            using (var conn = new SqlConnection(strConn))
            {
                conn.Open();
                var cmd = new SqlCommand("sp_GetNext", conn);
                cmd.CommandType = CommandType.StoredProcedure;

                // Input param
                SqlParameter pInput = new SqlParameter("@in", SqlDbType.Int);
                pInput.Direction = ParameterDirection.Input;
                pInput.Value = 1;
                cmd.Parameters.Add(pInput);
                
                // Output param
                SqlParameter pOutput = new SqlParameter("@out", SqlDbType.Int);
                pOutput.Direction = ParameterDirection.Output;
                cmd.Parameters.Add(pOutput);

                cmd.ExecuteNonQuery();

                Console.WriteLine(pOutput.Value);
            }
        }
    }
}



© csharpstudy.com