세션 상태 저장소 공급자 구현
업데이트: 2007년 11월
사용자 지정 세션 상태 저장소 공급자 구현에 대해 설명하고 샘플 공급자의 구현 방식을 보여 줍니다.
ASP.NET 세션 상태는 서로 다른 소스에 사용자 세션 데이터를 저장할 수 있도록 디자인되었습니다. 기본적으로 세션 상태 값과 정보는 ASP.NET 프로세스 내의 메모리에 저장됩니다. 세션 데이터를 상태 서버에 저장할 수도 있습니다. 상태 서버에서는 세션 데이터를 별도의 프로세스에 보관하며 ASP.NET 응용 프로그램이 종료되고 다시 시작되어도 데이터를 계속 유지합니다. 또 다른 방법은 여러 웹 서버에서 공유할 수 있는 SQL Server 데이터베이스에 세션 데이터를 저장하는 것입니다.
ASP.NET에 포함되어 있는 세션 상태 저장소를 사용하거나 사용자 고유의 세션 상태 저장소 공급자를 구현할 수 있습니다. 다음과 같은 요구 사항을 충족하기 위해 사용자 지정 세션 상태 저장소 공급자를 만들 수 있습니다.
FoxPro 데이터베이스나 Oracle 데이터베이스와 같이 SQL Server 이외의 데이터 소스에 세션 상태 정보를 저장해야 합니다.
.NET Framework와 함께 제공되는 공급자에서 사용한 데이터베이스 스키마와는 다른 데이터베이스 스키마를 사용하여 세션 상태 정보를 관리해야 합니다. 기존 SQL Server 데이터베이스에 미리 정의된 스키마를 사용하여 장바구니 데이터를 저장하는 경우를 예로 들 수 있습니다.
사용자 지정 세션 상태 저장소 공급자는 SessionStateStoreProviderBase 클래스를 상속하는 클래스를 만들어서 구현할 수 있습니다. 자세한 내용은 이 항목 뒷부분의 "필수 클래스" 단원을 참조하십시오.
세션 상태 모듈
세션 상태는 SessionStateModule 클래스를 통해 관리됩니다. 이 클래스는 요청의 각기 다른 시점에서 세션 데이터를 읽고 데이터 저장소에 기록하기 위해 세션 상태 저장소 공급자를 호출합니다. 요청을 시작하는 시점에서 SessionStateModule 인스턴스는 GetItemExclusive 메서드를 호출하거나 EnableSessionState 페이지 특성이 ReadOnly로 설정된 경우 GetItem 메서드를 호출하여 데이터 소스에서 데이터를 검색합니다. 요청을 끝내는 시점에서 세션 상태 값이 수정되었으면 SessionStateModule 인스턴스는 SessionStateStoreProviderBase.SetAndReleaseItemExclusive 메서드를 호출하여 업데이트된 값을 세션 상태 저장소에 기록합니다. SessionStateModule은 SessionStateStoreProviderBase 구현의 추가 멤버를 호출하여 새 세션을 초기화하고 HttpSessionState.Abandon 메서드를 호출할 때 데이터 저장소에서 세션 데이터를 삭제합니다. SessionStateStoreProviderBase 클래스의 각 멤버에 대해서는 이 항목 뒷부분의 "필수 클래스" 단원에서 자세히 설명합니다.
SessionStateModule 클래스는 SessionID 값을 결정하기 위해 세션 상태 저장소 공급자에 의존하지 않고 스스로 값을 결정합니다. 필요한 경우 ISessionIDManager 인터페이스를 상속하는 클래스를 만들어 사용자 지정 SessionIDManager을 구현할 수 있습니다. 자세한 내용은 ISessionIDManager의 "설명" 단원을 참조하십시오.
SessionStateModule은 데이터베이스 서버와 같은 보안 리소스에 액세스하기 위해 ASP.NET 프로세스 ID로 되돌아갑니다. <sessionState> 구성 요소의 useHostingIdentity 특성을 false로 설정하여 SessionStateModule 인스턴스가 IIS에서 제공한 ID를 가장하도록 지정할 수 있습니다. 예를 들어, Windows 통합 보안을 사용하도록 IIS 응용 프로그램을 구성했고 ASP.NET이 세션 관리를 위해 IIS에서 제공한 ID를 가장하도록 하려면 응용 프로그램에 대한 Web.config 파일의 <system.web> 구성 섹션에서 <identity impersonate="true" />를 지정하고 <sessionState> 구성 요소의 useHostingIdentity 특성을 false로 설정합니다. useHostingIdentity 특성이 true로 설정된 경우에는 데이터 소스에 연결할 때 프로세스 ID 또는 <identity> 구성 요소에 제공된 사용자 자격 증명(있는 경우)을 가장합니다. ASP.NET 프로세스 ID에 대한 자세한 내용은 ASP.NET 프로세스 ID 구성 및 ASP.NET 가장을 참조하십시오.
세션 저장소 데이터 잠금
ASP.NET 응용 프로그램은 동시에 실행되는 여러 요청에 응답할 수 있도록 다중 스레드 방식을 사용합니다. 동시에 실행되는 여러 요청에서 동일한 세션 정보에 액세스하려 할 수 있습니다. 프레임셋에 있는 여러 프레임이 모두 같은 응용 프로그램의 ASP.NET 웹 페이지를 참조하는 시나리오를 생각해 볼 수 있습니다. 프레임셋의 각 프레임에 대한 개별 요청들은 웹 서버에서 여러 스레드로 동시에 실행될 수 있습니다. 각 프레임에 대한 ASP.NET 페이지가 세션 상태 변수에 액세스하면 여러 스레드가 세션 저장소에 동시에 액세스하게 될 수 있습니다. 세션 저장소에서의 데이터 충돌과 예기치 않은 세션 상태 동작을 방지하기 위해 SessionStateModule 및 SessionStateStoreProviderBase 클래스에는 ASP.NET 페이지 하나를 실행하는 동안 특정 세션에 대한 세션 저장소 항목을 단독으로 잠그는 기능이 있습니다. EnableSessionState 특성이 ReadOnly로 표시된 경우에는 세션 저장소 항목에 잠금이 설정되지 않습니다. 그러나 동일 응용 프로그램의 다른 ASP.NET 페이지에서는 이 세션 저장소에 쓸 수 있으므로, 저장소에서 읽기 전용 세션 데이터를 요청하더라도 결국 잠긴 데이터가 해제될 때까지 기다려야 할 수 있습니다.
잠금은 GetItemExclusive 메서드를 호출하는 요청 시작 부분에서 세션 저장소 데이터에 설정됩니다. 요청이 완료되면 SetAndReleaseItemExclusive 메서드를 호출하는 동안 잠금이 해제됩니다.
SessionStateModule 인스턴스에서 GetItemExclusive 또는 GetItem 메서드를 호출하는 동안 잠긴 세션 데이터가 발견되면 잠금이 해제될 때까지 또는 ExecutionTimeout 속성에 지정된 시간이 경과할 때까지 0.5초 간격으로 세션 데이터를 다시 요청합니다. 요청 제한 시간이 초과하면 SessionStateModule에서 ReleaseItemExclusive 메서드를 호출하여 세션 저장소 데이터를 해제하고 그 시점의 세션 저장소 데이터를 요청합니다.
잠긴 세션 저장소 데이터는 현재 응답에 대해 SetAndReleaseItemExclusive 메서드를 호출하기 전에 개별 스레드에서 ReleaseItemExclusive 메서드를 호출하여 해제될 수 있습니다. 이렇게 하면 이미 다른 세션에서 해제 및 수정한 세션 상태 저장소 데이터를 SessionStateModule 인스턴스가 설정 및 해제하게 됩니다. 이러한 경우를 방지하기 위해 SessionStateModule에는 잠긴 세션 데이터 저장소 데이터를 수정하기 위해 각 요청에 대한 잠금 식별자가 포함됩니다. 세션 저장소 데이터는 데이터 저장소의 잠금 식별자가 SessionStateModule에서 제공한 잠금 식별자와 일치하는 경우에만 수정됩니다.
만료된 세션 저장소 데이터 삭제
세션에 대해 Abandon 메서드를 호출하면 해당 세션의 데이터가 RemoveItem 메서드를 사용하여 데이터 저장소에서 삭제됩니다. 그렇지 않은 경우에는 세션에서 이후의 요청에 사용할 수 있도록 세션 데이터 저장소에 데이터가 유지됩니다.
만료된 세션 데이터를 삭제하기 위한 메커니즘은 데이터 소스의 기능에 따라 달라집니다. 세션 Timeout 속성에 따라 만료된 세션 데이터를 삭제하도록 데이터 소스를 구성할 수 있으면 SetItemExpireCallback 메서드를 사용하여 Session_OnEnd 이벤트에 대한 대리자를 참조하고 만료된 세션 데이터 삭제 시 이 이벤트를 발생시킬 수 있습니다.
ApplicationName
세션 범위를 유지하기 위해 세션 상태 공급자는 각 응용 프로그램에 대해 세션 정보를 고유하게 저장합니다. 이렇게 하면 중복 세션 식별자가 발견되는 경우에도 여러 ASP.NET 응용 프로그램이 충돌을 일으키지 않고 동일한 데이터 소스를 사용할 수 있습니다.
세션 상태 저장소 공급자는 세션 정보를 각 응용 프로그램에 대해 고유하게 저장하기 때문에 사용자는 데이터 스키마, 쿼리 및 업데이트에 응용 프로그램 이름이 포함되어 있는지 확인해야 합니다. 예를 들어, 다음 명령은 데이터베이스에서 세션 데이터를 검색하는 데 사용될 수 있습니다.
SELECT * FROM Sessions
WHERE SessionID = 'ABC123' AND ApplicationName = 'MyApplication'
또는 세션 식별자 및 응용 프로그램 이름을 조합하여 세션 상태 데이터 저장소의 한 항목에 대한 고유 식별자로 저장할 수 있습니다.
필수 클래스
세션 상태 저장소 공급자를 구현하려면 SessionStateStoreProviderBase 추상 클래스를 상속하는 클래스를 만듭니다. SessionStateStoreProviderBase 클래스는 ProviderBase 추상 클래스를 상속하므로 사용자는 필요한 ProviderBase 클래스 멤버도 구현해야 합니다. 다음 표에서는 ProviderBase 및 SessionStateStoreProviderBase 추상 클래스에서 구현해야 하는 속성과 메서드를 보여 주고 각각에 대해 설명합니다. 각 멤버에 대한 구현을 보려면 샘플 세션 상태 저장소 공급자를 참조하십시오.
필요한 ProviderBase 멤버
멤버 |
설명 |
---|---|
Initialize 메서드 |
구성 설정의 NameValueCollection 인스턴스와 공급자 이름을 입력으로 사용합니다. 이 메서드는 구성 파일(Machine.config 또는 Web.config)에 지정된 구현 관련 값과 옵션을 비롯한 공급자 인스턴스에 대한 속성 값을 설정하는 데 사용됩니다. |
필요한 SessionStateStoreProvider 멤버
멤버 |
설명 |
---|---|
현재 요청에 대한 HttpContext 인스턴스를 입력으로 사용하고 세션 상태 저장소 공급자에서 필요한 모든 초기화 작업을 수행합니다. |
|
EndRequest 메서드 |
현재 요청에 대한 HttpContext 인스턴스를 입력으로 사용하고 세션 상태 저장소 공급자에서 필요한 모든 정리 작업을 수행합니다. |
Dispose 메서드 |
세션 상태 저장소 공급자에서 더 이상 사용하지 않는 모든 리소스를 해제합니다. |
GetItemExclusive 메서드 |
현재 요청에 대한 HttpContext 인스턴스 및 현재 요청에 대한 SessionID 값을 입력으로 사용합니다. 세션 데이터 저장소에서 세션 값과 정보를 검색하고 요청 기간 동안 데이터 저장소에서 세션 항목 데이터를 잠급니다. GetItemExclusive 메서드는 데이터 저장소에서 현재 세션 상태 항목의 상태에 대한 SessionStateModule 호출을 알리는 여러 출력 매개 변수 값을 설정합니다. 데이터 저장소에 세션 항목 데이터가 없으면 GetItemExclusive 메서드가 locked 출력 매개 변수를 false로 설정하고 null을 반환합니다. 그러면 SessionStateModule이 CreateNewStoreData 메서드를 호출하여 요청에 대해 새로운 SessionStateStoreData 개체를 만듭니다. 데이터 저장소에 세션 항목 데이터가 있지만 데이터가 잠긴 경우 GetItemExclusive 메서드는 locked 출력 매개 변수를 true로 설정하고, lockAge 출력 매개 변수를 현재 날짜 및 시간에서 항목을 잠근 시간 및 날짜를 뺀 시각으로 설정하고, lockId 출력 매개 변수를 데이터 저장소에서 검색한 잠금 식별자로 설정하고, null을 반환합니다. 그 결과 SessionStateModule은 세션 항목 정보를 검색하고 데이터에 대한 잠금을 얻기 위해 0.5초 간격으로 GetItemExclusive 메서드를 다시 호출합니다. lockAge 출력 매개 변수에 설정된 값이 ExecutionTimeout 값을 초과하면 SessionStateModule이 ReleaseItemExclusive 메서드를 호출하여 세션 항목 데이터에 대한 잠금을 해제한 다음 GetItemExclusive 메서드를 다시 호출합니다. actionFlags 매개 변수는 regenerateExpiredSessionId 특성이 true로 설정된 경우 해당 Cookieless 속성이 true인 세션에 사용됩니다. actionFlags 값이 InitializeItem(1)으로 설정된 경우 세션 데이터 저장소의 항목은 초기화해야 하는 새 세션을 나타냅니다. 세션 데이터 저장소에서 초기화되지 않은 항목은 CreateUninitializedItem 메서드를 호출하여 만들어집니다. 세션 데이터 저장소의 항목이 아직 초기화되지 않은 경우 actionFlags 매개 변수는 0으로 설정됩니다. 공급자에서 쿠키 없는 세션을 지원하는 경우 actionFlags 출력 매개 변수를 현재 항목에 대한 세션 데이터 저장소에서 반환된 값으로 설정합니다. 요청된 세션 저장소 항목의 actionFlags 매개 변수 값이 InitializeItem 열거 값(1)과 같으면 GetItemExclusive 메서드는 actionFlagsout 매개 변수를 설정한 후 데이터 저장소의 값을 0으로 설정합니다. |
GetItem 메서드 |
이 메서드는 데이터 저장소에서 세션 항목을 잠그려고 시도하지 않는다는 점을 제외하면 GetItemExclusive 메서드와 같은 작업을 수행합니다. GetItem 메서드는 EnableSessionState 특성이 ReadOnly로 설정된 경우 호출됩니다. |
현재 요청에 대한 HttpContext 인스턴스, 현재 요청에 대한 SessionID 값, 저장할 현재 세션 값을 포함하는 SessionStateStoreData 개체, 현재 요청에 대한 잠금 식별자 및 저장할 데이터가 새로운 세션 또는 기존 세션에 저장되는지 여부를 나타내는 값을 입력으로 사용합니다. newItem 매개 변수가 true인 경우 SetAndReleaseItemExclusive 메서드는 제공된 값으로 새 항목을 데이터 저장소에 삽입합니다. 그렇지 않은 경우 데이터 저장소의 기존 항목이 제공된 값으로 업데이트되고 데이터 잠금이 모두 해제됩니다. 현재 응용 프로그램의 세션 데이터만 제공된 SessionID 값과 일치하고 잠금 식별자 값이 업데이트됩니다. SetAndReleaseItemExclusive 메서드가 호출된 후 SessionStateModule이 세션 항목 데이터의 만료 날짜 및 시간을 업데이트하기 위해 ResetItemTimeout 메서드를 호출합니다. |
|
현재 요청에 대한 HttpContext 인스턴스, 현재 요청에 대한 SessionID 값, 현재 요청에 대한 잠금 식별자를 입력으로 사용하고 세션 데이터 저장소에서 항목에 대한 잠금을 해제합니다. 이 메서드는 GetItem 또는 GetItemExclusive 메서드가 호출되고 요청된 항목이 잠기지만 잠금 시간이 ExecutionTimeout 값을 초과하도록 데이터 저장소가 지정하는 경우에 호출됩니다. 이 메서드는 잠금을 해제하여 다른 요청에서 항목을 사용할 수 있도록 합니다. |
|
RemoveItem 메서드 |
현재 요청에 대한 HttpContext 인스턴스, 현재 요청에 대한 SessionID 값, 현재 요청에 대한 잠금 식별자를 입력으로 사용하고 데이터 저장소 항목이 제공된 SessionID 값, 현재 응용 프로그램 및 제공된 잠금 식별자와 일치하는 데이터 저장소에서 세션 정보를 삭제합니다. 이 메서드는 Abandon 메서드가 호출될 때 호출됩니다. |
현재 요청의 HttpContext 인스턴스, 현재 요청의 SessionID 값 및 현재 요청의 잠금 식별자를 입력으로 사용하고 InitializeItem의 actionFlags 값을 사용하여 초기화되지 않은 항목을 세션 데이터 저장소에 추가합니다. CreateUninitializedItem 메서드는 regenerateExpiredSessionId 특성이 true로 설정된 경우 쿠키 없는 세션에 사용됩니다. 이와 같은 설정에서는 만료된 세션 ID가 발견되는 경우 SessionStateModule을 통해 새 SessionID 값이 생성됩니다. 새 SessionID 값을 생성하는 프로세스를 진행하려면 새로 생성된 세션 ID가 포함되는 URL로 브라우저를 리디렉션해야 합니다. 만료된 세션 ID가 포함된 초기 요청을 진행하는 동안 CreateUninitializedItem 메서드가 호출됩니다. SessionStateModule에서 새 SessionID 값을 획득하여 만료된 세션 ID를 대체하고 나면 CreateUninitializedItem 메서드를 호출하여 초기화되지 않은 항목을 세션 상태 데이터 저장소에 추가합니다. 그런 다음 브라우저는 새로 생성된 SessionID 값이 포함된 URL로 리디렉션됩니다. 세션 데이터 저장소에 초기화되지 않은 항목이 있으면 새로 생성된 SessionID 값을 포함하는 리디렉션된 요청이 만료된 세션에 대한 요청으로 잘못 처리되지 않고 새로운 세션으로 대신 처리될 수 있습니다. 세션 데이터 저장소의 초기화되지 않은 항목은 새로 생성된 SessionID 값과 관련되며, 만료 날짜 및 시간과 GetItem 및 GetItemExclusive 메서드의 actionFlags 매개 변수에 해당하는 값을 비롯한 기본 값만 포함합니다. 세션 상태 저장소에 있는 초기화되지 않은 항목은 InitializeItem 열거 값(1)과 같은 actionFlags 값을 포함해야 합니다. 이 값은 GetItem 및 GetItemExclusive 메서드를 통해 SessionStateModule에 전달되고 SessionStateModule에 대해 현재 세션이 새 세션임을 지정합니다. 그런 다음 SessionStateModule에서 새 세션을 초기화하고 Session_OnStart 이벤트를 발생시킵니다. |
|
현재 요청의 HttpContext 인스턴스와 현재 세션의 Timeout 값을 입력으로 사용하고 비어 있는 ISessionStateItemCollection 개체, HttpStaticObjectsCollection 컬렉션 및 지정된 Timeout 값이 있는 새 SessionStateStoreData 개체를 반환합니다. ASP.NET 응용 프로그램용 HttpStaticObjectsCollection 인스턴스는 GetSessionStaticObjects 메서드를 사용하여 검색할 수 있습니다. |
|
Global.asax 파일에 정의된 Session_OnEnd 이벤트를 참조하는 대리자를 입력으로 사용합니다. 세션 상태 저장소 공급자가 Session_OnEnd 이벤트를 지원하는 경우 SessionStateItemExpireCallback 매개 변수에 대한 로컬 참조가 설정되고 메서드는 true를 반환합니다. 그렇지 않으면 메서드가 false를 반환합니다. |
샘플 공급자
Access 데이터베이스에서 세션 정보를 관리하는 사용자 지정 세션 상태 저장소 공급자를 구현하는 방법의 예제를 보려면 샘플 세션 상태 저장소 공급자를 참조하십시오.