이 문서에서는 Visual C# 클래스에서 COM+(구성 요소 서비스) 트랜잭션을 사용하는 방법을 단계별로 설명합니다. 데이터베이스 작업의 집합은 하나의 단위로 간주됩니다. 모든 작업이 성공하면 전체 트랜잭션이 성공하고 한 작업이라도 실패하면 전체 트랜잭션이 실패합니다. 실패하는 경우 시도된 모든 데이터베이스 작업은 기본 데이터베이스에 게시되지 않습니다.
요구 사항
다음은 권장 하드웨어, 소프트웨어, 네트워크 인프라, 기술과 지식 및 필수 서비스 팩 목록입니다.
- Microsoft Windows 2000 Server SP1
- Microsoft 인터넷 정보 서비스(IIS) 4.0 이상
- Microsoft Internet Explorer 5.0, 5.5 또는 6.0
이 문서에서는 사용자가 다음 항목에 대해 잘 알고 있는 것으로 가정합니다.
- 트랜잭션 개념 및 처리
- COM+(구성 요소 서비스)
COM+ 트랜잭션 서비스
Microsoft .NET Framework에서 System.EnterpriseServices 네임스페이스를 사용하여 트랜잭션 처리를 구현할 수 있습니다. COM+ 트랜잭션 서비스에 액세스하려면 클래스를 만들어야 합니다. 이렇게 하려면 다음과 같이 하십시오.
- Visual Studio .NET 또는 Visual Studio 2005를 시작합니다.
- 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 누릅니다.
- 프로젝트 형식에서 Visual C# 프로젝트를 누른 다음 템플릿에서 클래스 라이브러리를 누릅니다. 프로젝트에 prjEnterprise라는 이름을 지정합니다.
참고 Visual Studio 2005의 경우에는 프로젝트 형식에서 Visual C#를 누른 다음 템플릿에서 클래스 라이브러리를 누릅니다. 프로젝트에 prjEnterprise라는 이름을 지정합니다. - 기본적으로 Class1이 만들어집니다.
- 솔루션 탐색기에서 참조를 마우스 오른쪽 단추로 누른 다음 참조 추가를 누릅니다.
- 참조 추가 대화 상자가 나타납니다. .NET 탭의 구성 요소 이름에서 System.EnterpriseServices를 두 번 누릅니다.
- 선택한 구성 요소에 System.EnterpriseServices가 나타나는지 확인합니다. 확인을 누릅니다.
- Class1.cs 파일의 다른 문 앞에 다음 코드를 추가합니다.
using System.EnterpriseServices; using System.Data.SqlClient;
- Class1.cs 파일에 clsES라는 새 클래스를 추가합니다.
- COM+ 트랜잭션 서비스를 사용하려면 다음과 같이 클래스(clsES)가 ServicedComponent에서 기능을 상속해야 합니다.
public class clsES : ServicedComponent
- Transaction 특성은 다음과 같이 클래스에 대한 트랜잭션 지원 수준을 지정하는 데 사용됩니다.
[Transaction(TransactionOption.Required)]public class clsES : ServicedComponent
- clsES 클래스에 네 가지 입력 정수 매개 변수를 받는 메서드를 만들고 dbAccess라는 이름을 지정합니다. 처음 두 매개 변수는 제품 ID와 해당 제품의 주문 단위를 제공합니다. 그 다음 두 매개 변수는 제품 ID와 해당 제품의 재고 단위를 제공합니다. 이 메서드는 트랜잭션으로 처리되어야 하는 지정된 제품 ID에 대해 데이터베이스 작업의 집합을 수행합니다.
void dbAccess(int pID1,int onOrder, int pID2, int inStock)
- dbAccess 메서드에서 Northwind 데이터베이스에 대한 SQL 연결 개체를 만든 다음 연결을 엽니다. 다음 데이터베이스를 사용하여 데이터베이스 작업이 수행됩니다.
참고 다음 연결 문자열 매개 변수를 SQL Server 서버에 대한 올바른 값으로 변경하십시오.SqlConnection Conn = new SqlConnection("user id=<username>;password=<strong password>;Initial Catalog=northwind;Data Source=2E124\\SQL;"); Conn.Open();
- 데이터베이스 처리 중 발생할 수 있는 예외를 알리도록 try 블록을 설정합니다. 트랜잭션을 중단하기 위해서는 이러한 예외를 catch해야 합니다. try 블록에는 두 가지 데이터베이스 작업이 포함됩니다. 각 작업은 지정된 제품 테이블 레코드에서 서로 다른 필드를 업데이트합니다.
try {
- 제품 테이블을 업데이트합니다. 처음 두 입력 매개 변수에 지정된 ID에 해당하는 제품의 onOrder 값으로 UnitsonOrder 필드를 업데이트합니다. 다음 SQL 명령을 사용하여 이 SQL 업데이트를 실행하십시오.
SqlCommand sqlCommand = new SqlCommand("UPDATE myProducts SET UnitsonOrder = " + onOrder + " WHERE productID = " + pID1, Conn); sqlCommand.ExecuteNonQuery();
- 제품 테이블을 다시 업데이트합니다. 세 번째와 네 번째 입력 매개 변수에 지정된 ID에 해당하는 제품의 inStock 값으로 UnitsinStock 필드를 업데이트합니다. 다음 SQL 명령을 사용하여 이 SQL 업데이트를 실행하십시오.
sqlCommand.CommandText = "UPDATE myProducts SET UnitsinStock = " + inStock + " WHERE productID = " + pID2; sqlCommand.ExecuteNonQuery();
- 이러한 업데이트가 COM+ 트랜잭션에 속해 있으므로 하나의 단위로 커밋되어야 합니다. 오류가 발생하지 않을 경우 System.EnterpriseServices 네임스페이스에서 contextUtil 클래스의 setComplete 메서드를 사용하여 트랜잭션(이 경우에는 위의 두 업데이트)을 커밋합니다.
ContextUtil.SetComplete();
- Northwind 데이터베이스와의 연결이 닫힙니다.
Conn.Close(); }
- 전체 트랜잭션을 중단할 수 있도록 SQL 명령을 실행하는 동안 발생하는 예외를 catch해야 합니다.
catch(Exception e){
- System.EnterpriseServices 네임스페이스에서 contextUtil 클래스의 setAbort 메서드를 사용하여 전체 트랜잭션을 중단합니다. 첫 번째 업데이트가 성공하고 두 번째 업데이트가 실패하면 두 업데이트 모두 제품 테이블에 게시되지 않습니다. catch한 예외가 호출자에게 throw되고 트랜잭션 실패를 알립니다.
ContextUtil.SetAbort(); throw e; }
- 이 구성 요소가 제대로 작동하려면 구성 요소에 강력한 이름이 있어야 합니다. 강력한 이름을 생성한 다음 강력한 이름으로 어셈블리에 서명하십시오. 이렇게 하려면 다음과 같이 하십시오.
- Visual Studio .NET 명령 프롬프트에서 sn.exe -k snEnterprise.snk를 입력하여 키 파일을 만듭니다. 강력한 이름으로 어셈블리에 서명하는 방법에 대한 자세한 내용은 .NET Framework SDK 설명서를 참조하십시오.
- snEnterprise.snk를 프로젝트 폴더로 복사합니다.
- AssemblyInfo.vc에서 다른 어셈블리 특성 문의 앞이나 뒤에 다음 코드를 추가합니다.
[assembly: AssemblyKeyFileAttribute("..\\..\\snEnterprise.snk")]
- 저장한 다음 프로젝트를 빌드합니다.
전체 코드 예제
참고 다음 연결 문자열 매개 변수를 SQL Server 서버에 대한 올바른 값으로 변경하십시오.
using System;
using System.Data;
using System.Data.SqlTypes;
using System.Data.Common;
using System.EnterpriseServices;
using System.Data.SqlClient;
namespace prjEnterprise
{
[Transaction(TransactionOption.Required)]public class clsES:ServicedComponent
{
public SqlConnection Conn;
public void dbAccess(int pID1, int onOrder, int pID2, int inStock)
{
try
{
SqlConnection Conn = new SqlConnection("user id=<username>;password=<strong password>;Initial Catalog=northwind;Data Source=2E124\\SQL;");
Conn.Open();
SqlCommand sqlCommand = new SqlCommand("UPDATE myProducts SET UnitsonOrder = " + onOrder + " WHERE productID = " + pID1, Conn);
sqlCommand.ExecuteNonQuery();
sqlCommand.CommandText = "UPDATE myProducts SET UnitsinStock = " + inStock + " WHERE productID = " + pID2;
sqlCommand.ExecuteNonQuery();
ContextUtil.SetComplete();
Conn.Close();
}
catch (Exception e)
{
ContextUtil.SetAbort();
throw e;
}
finally
{
}
}
}
}
작동 여부 확인
이 코드를 테스트하기 위해 clsES 프로젝트를 사용하는 콘솔 응용 프로그램을 만듭니다. 첫 번째 경우에는 트랜잭션이 성공하고 지정된 제품의 onOrder 및 inStock 필드가 업데이트됩니다. 두 번째 경우에는 지정된 제품의 onOrder 필드에 대한 업데이트가 성공하지만 지정된 제품 번호가 제품 테이블에 없기 때문에 제품의 inStock 필드에 대한 업데이트가 실패합니다. 이에 따라 트랜잭션이 실패하고 무시됩니다.
- Visual Studio .NET 또는 Visual Studio 2005의 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 누릅니다.
- 프로젝트 형식에서 Visual C# 프로젝트를 누른 다음 템플릿에서 콘솔 응용 프로그램을 누릅니다.
참고 Visual Studio 2005의 경우에는 프로젝트 형식에서 Visual C#를 누른 다음 템플릿에서 콘솔 응용 프로그램을 누릅니다. - 이름 입력란에 testES를 입력합니다. 솔루션에 추가 옵션이 선택되어 있는지 확인합니다.
- 확인을 눌러 솔루션에 이 프로젝트를 추가합니다.
- testES가 clsES를 테스트하도록 하려면 참조를 추가해야 합니다. 위에서 추가한 솔루션 탐색기의 testES에서 참조를 마우스 오른쪽 단추로 누른 다음 참조 추가를 누릅니다.
- 참조 추가 대화 상자가 나타납니다. 프로젝트 탭에서 prjEnterprise를 두 번 누릅니다.
- 선택한 구성 요소에 참조가 나타납니다. 확인을 눌러 프로젝트에 이 참조를 추가합니다.
- System.EnterpriseServices 라이브러리에 프로젝트에 대한 참조를 추가합니다. 솔루션 탐색기에서 참조를 마우스 오른쪽 단추로 누른 다음 참조 추가를 누릅니다.
- 참조 추가 대화 상자가 나타납니다. .NET 탭의 구성 요소 이름에서 System.EnterpriseServices를 두 번 누릅니다.
- 선택한 구성 요소에 System.EnterpriseServices가 나타나는지 확인합니다. 확인을 누릅니다.
- 콘솔 응용 프로그램(testES)을 마우스 오른쪽 단추로 누른 다음 시작 프로젝트로 설정을 누릅니다.
- Class1 클래스의 Main 함수에 다음 소스 코드를 붙여 넣습니다.
prjEnterprise.clsES myTest = new prjEnterprise.clsES(); try { myTest.dbAccess(1, 777, 2, 888); Console.WriteLine("TRANSACTION ONE -- SUCCESS"); myTest.dbAccess(1, 5, 2, -20); Console.WriteLine("TRANSACTION TWO -- SUCCESS"); } catch (Exception e) { Console.WriteLine("TRANSACTION FAILURE"); }
- F5 키를 눌러 테스트 코드를 실행합니다.
7단계의 코드에서 첫 번째 dbAccess 호출은 성공합니다. 제품 1과 제품 2가 제품 테이블에 있습니다. 제품 1의 onOrder 필드가 777로 업데이트되고 제품 2의 inStock 필드가 888로 업데이트됩니다. 이 트랜잭션이 성공했기 때문에 출력 창에 다음 메시지가 표시됩니다.
두 번째 dbAccess 호출은 실패합니다. 따라서 제품 테이블에 대한 dbAccess의 업데이트 문이 데이터베이스에 게시되지 않습니다. 제품 1의 onOrder 필드가 5로 업데이트되었을 수 있지만 제품 2의 inStock 필드는 -20으로 설정될 수 없습니다. 제품 테이블 정의에 정의되어 있는 제약 조건 때문에 inStock에 음수 값이 허용되지 않습니다.
따라서 이 dbAccess 호출은 실패하고 전체 트랜잭션도 실패합니다. 제품 테이블은 dbAccess 호출 전의 상태를 유지합니다. catch 문은 dbAccess에서의 트랜잭션 실패 알림을 처리하며, 출력 창에는 다음 오류 메시지가 표시됩니다.TRANSACTION FAILURE - SQL Server 엔터프라이즈 관리자를 사용하여 Northwind 제품 테이블의 내용을 검토합니다. 제품 1을 보면 onOrder 필드가 777입니다. 제품 2를 보면 inStock 필드가 888입니다. 따라서 두 필드에 이와 다른 값을 설정하는 두 번째 dbAccess 호출은 실패했음을 알 수 있습니다.
문제 해결
- COM+ 서비스를 사용하는 프로젝트가 강력한 이름을 갖고 있는지 확인합니다.
- COM+ 서비스를 사용하는 모든 클래스는 서비스 대상 구성 요소에서 상속해야 합니다. 서비스 대상 구성 요소는 System.EnterpriseServices 네임스페이스에 있습니다.
- 디버깅하는 동안 트랜잭션이 커밋되거나 중단되기 전에 시간이 초과될 수 있습니다. 시간 초과를 막으려면 트랜잭션 특성에서 제한 시간 속성을 사용하십시오. 다음 예제에서 관련 메서드의 트랜잭션 완료 제한 시간은 1,200초입니다.
[Transaction(TransactionOption.Required,timeout:=1200)]
'IT > Visual Studio' 카테고리의 다른 글
엔티티프레임워크에서 linq 형 변환 방법 (0) | 2019.02.14 |
---|---|
[C#] RS232 통신 샘플 코드 (0) | 2018.07.27 |
[C#] USB 통신 샘플 소스 (0) | 2018.07.26 |
JSon 문자열을 C# DataTable로 변환 코드 (0) | 2018.05.02 |
[VisualStudio] 사용자 지정 이벤트 로그를 만들 수 있는 권한 부여 (0) | 2018.04.10 |
[Visual Studio] 강력키 생성방법 (0) | 2018.04.07 |
[Visual Studio] vs2005설치후 vs2003설치시 주의할 점 (0) | 2018.04.03 |
[C#] 엑셀 제어 (0) | 2018.04.01 |