Getting Started: Transactional Component¶
NeoDEEX 는 Fox Transactions 기능을 통해 선언적인 자동 트랜잭션 기능을 제공합니다. 이 문서는 Fox Transactions 의 선언적인 자동 트랜잭션 기능을 사용하는 방법에 대해 구체적으로 살펴볼 것입니다.
Overview¶
Fox Transaction 은 System.Transactions
네임스페이스가 제공하는 Ambient Transaction 기능을 활용하여 개발자가 트랜잭션 처리를 간편하게 수행할 수 있는 수행 문맥(Executeion Context)을 제공합니다. 개발자는 단순히 FoxComponentBase
에서 파생된 클래스에서 메서드를 작성하고 데이터베이스 액세스를 수행하기만 하면 트랜잭션이 자동으로 시작됩니다. 메서드 내에서 오류(예외)가 발생하면 트랜잭션은 자동으로 롤백되며 오류 없이 메서드가 종료되면 트랜잭션은 커밋됩니다.
이 문서와 관련된 전체 예제 코드는 다음 링크를 참고 하십시요.
Creating a test app & database¶
Fox Transactions 을 사용하는 방법을 보여주기 위해 테스트용 App 을 생성하고 데이터베이스 구성을 해야 합니다. 간단한 App 이므로 Console App 을 사용할 것이며 테스트를 위해 간단한 테이블을 생성해야 합니다.
Creating a console app project¶
예제를 위해 Console App 프로젝트를 작성합니다.
Information
Fox Transactions 는 특정 프로젝트 타입에 구애 받지 않습니다. ASP.NET Core App 이나 Library 프로젝트 등 거의 모든 프로젝트 템플릿에서 사용할 수 있습니다. 이 예제는 간단한 예제이므로 Console App 프로젝트를 사용하지만, 실제 어플리케이션에서는 Web API 프로젝트에서 Fox Transactions 를 가장 많이 사용합니다.
-
Visual Studio 를 구동하고 새 프로젝트 생성을 선택합니다. 그리고 콘솔 어플리케이션 프로젝트 템플릿을 선택합니다.
-
프로젝트 구성 대화 상자에서 프로젝트 이름을
TransactionalComponent
로 설정합니다. -
프로젝트 추가 정보 대화 상자에서
.NET 8.0
을 선택합니다.Information
이 예제에서는 익숙한
Main
메서드가 나타나도록Do not use top-level statements
를 선택했습니다.Note
Fox Transaction 의 모든 기능을 사용하고자 한다면
.NET 7.0
이상 버전을 선택해야 합니다..NET 6.0
이하 버전은 분산 트랜잭션 등 일부 기능을 지원하지 않습니다. -
Fox Transactions 를 사용하기 위해
NeoDEEX.Transactions
패키지를 추가 합니다.또한 데이터베이스에 액세스하기 위해 데이터베이스 관련 패키지를 추가 합니다. 이 예제에서는 SQL Server 를 사용할 것이기 때문에
NeoDEEX.Data.SqlClient
패키지를 추가 합니다. 다른 데이터베이스를 사용하고자 한다면 다음 목록을 참고하여 데이터베이스 패키지를 추가하면 됩니다.- Oracle :
NeoDEEX.Data.OracleClient
- PostgreSQL :
NeoDEEX.Data.NpgsqlClient
- MySQL :
NeoDEEX.Data.MySqlClient
- ODBC :
NeoDEEX.Data.Odbc
- Oracle :
-
데이터베이스 연결 문자열 등을 위해 NeoDEEX 구성 설정 파일을 추가 합니다. 프로젝트 아이템 추가 메뉴를 선택하고 JSON 파일 템플릿에서 파일 이름을
neodeex.config.json
로 지정합니다.Warning
NeoDEEX 구성 파일 이름은 명시적으로 바꾸지 않는 한
neodeex.config.json
이므로 파일 이름 지정에 주의해야 합니다.솔루션 탐색기에서 추가된
neodeex.config.json
파일을 선택하고 설정(properties)에서Copy to Output Directory
속성의 값이Copy if newer
임을 확인하십시요. -
neodeex.config.json
파일의 내용은 다음과 같이 지정합니다.SQL Server 대신 다른 데이터베이스를 사용한다면
type
속성의 값을 다음과 같이 지정하고, 각 데이터베이스에 맞는 연결 문자열을 사용하십시요.- Oracle:
NeoDEEX.Data.OracleClient.FoxOracleDbAccess
- PostgreSQL:
NeoDEEX.Data.NpgsqlClient.FoxNpgsqlDbAccss
- MySQL:
NeoDEEX.Data.MySqlClient.FoxMysqlDbAccess
- ODBC:
NeoDEEX.Data.Odbc.FoxOdbcDbAccess
이제 다음 코드를 사용하여 구성 설정에 명시된 연결 문자열을 사용하여 원하는 데이터베이스에 접속이 가능합니다.
- Oracle:
Configuring database¶
테스트에 사용할 데이터베이스에 접속하여 테스트용 테이블을 생성합니다.
Adding basic transactional component¶
Fox Transactions 기능들은 FoxComponentBase
클래스에서 파생된 클래스를 통해 제공됩니다. 따라서 다음에 설명하는 지침에 따라 트랜잭션 기능을 갖춘 컴포넌트(객체)를 작성해 보도록 합시다.
Information
추후 FoxComponentBase
클래스에서 파생되지 않았더라도 IFoxComponent
인터페이스를 구현하는 클래스에 대해 Fox Transactions 기능을 사용하는 방식도 지원될 것입니다.
-
프로젝트에
TxComp
클래스를 추가 합니다. 이 클래스의 베이스 클래스를FoxComponentBase
로 지정합니다. 이를 위해NeoDEEX.Transactions
네임스페이스를 사용해야 합니다. -
TxComp
클래스에 데이터를 삽입하는InsertData
메서드를 다음과 같이 추가 합니다.메서드에
FoxTransactionAttribute
특성이 사용되었음에 주목하십시요. 이 특성은 메서드가 트랜잭션을 어떻게 다룰지를 설정합니다.FoxTransactionOption
열거타입의Required
값은 이 메서드가 항상 트랜잭션을 사용함의 의미합니다. 이 메서드가 호출되기 전에 이미 트랜잭션이 시작되었다면 이 트랜잭션에 참여(enlist)하며 그렇지 않은 경우 새로운 트랜잭션을 시작하게 됩니다. -
InsertData
메서드를 포함하는ITxComp
인터페이스를 선언하고TxComp
클래스가 구현하도록 코드를 수정합니다. 다음은ITxComp
인터페이스TxComp
클래스의 전체 코드를 보여 줍니다. -
Main
메서드에서TxComp
클래스의InsertData
메서드를 호출하도록 다음과 같이 코드를 작성합니다.위 코드는
TxComp
객체를 생성하고FoxComponentBase
클래스에서 제공하는CrateExecution<T>
메서드를 호출하여 Fox Transactions 기능을 수행하는 프록시(proxy) 객체를 생성합니다. 그리고 이 프록시 객체에 대한 인터페이스를 통해InsertData
메서드를 호출합니다. -
프로젝트를 빌드하고 수행합니다. 그리고 이 예제에서 사용하는 데이터베이스에 접속하여 데이터가 삽입되었는지 확인합니다.
-
(Optional)
InsertData
메서드가 수행될 때 트랜잭션이 사용되었는지 확인하기 위해 SQL Server Profiler 를 사용할 수 있습니다.Information
SQL Server 가 아닌 다른 데이터베이스에 접속하였다면 해당 데이터베이스에서 제공하는 모니터링 도구를 사용할 수 있습니다.
- SQL Server Profiler 를 구동하고 테스트에 사용한 데이터베이스에 연결합니다.
- 추적 속성(Trace Properteis) 대화 상자에서 감시할 이벤트로
Transaction
카테고리의TM: Begin Tran complete
이벤트와TM: Commit Tran complete
이벤트를 선택합니다. TxTestTable
데이터를 삭제(DELETE FROM TxTestTable
)하거나InsertData
매개변수의 값을990
이 아닌 값으로 수정합니다.-
TransactionalComponent
프로젝트를 수행하고 Sql Server Profiler 가 표시하는 이벤트를 관찰합니다.INSERT
문장을 수행하기 전에 트랜잭션이 시작되고 수행 완료 후 트랜잭션이 COMMIT 되는 것을 확인할 수 있습니다. -
Fox Transactions 기능을 사용하지 않는 경우 트랜잭션이 수행되지 않는 것을 확인하기 위해 프록시가 아닌
TxComp
객체에 대해 직접 호출하도록 코드를 수정합니다.동일하게 SQL Server Profiler 를 사용하여 모니터링 하면서 다시 수행을 해 봅니다.
Warning
새로운 테스트 전에 기존에 추가된 데이터를 삭제하거나
InsertData
매개변수의 값을990
이 아닌 값으로 수정해야 합니다.Fox Transactions 기능을 사용하지 않고 동일 코드를 수행했을 때 트랜잭션과 관련된 이벤트를 관찰할 수 없음을 확인하십시요.
-
예외가 발생할 때 트랜잭션이 롤백되는 것을 확인하기 위해
InsertData
메서드에서 예외를 발생시키도록 다음과 같이 수정합니다. -
Main
메서드에서 발생한 예외를 무시하도록 다음과 같이 코드를 수정합니다. -
프로젝트를 빌드하고 수행합니다. 그리고 데이터베이스 데이터가 추가되었는지 확인합니다. 예외가 발생하였으므로 트랜잭션이 롤백되어 데이터가 추가되지 않았을 것입니다.
Warning
이전에 테스트를 진행했다면 INSERT 수행 시 중복키 오류가 발생할 수도 있습니다. 따라서 데이터를 먼저 삭제하거나
InsertData
매개변수의 값을990
이 아닌 값으로 수정하고 테스트를 수행해야 합니다. -
Fox Transactions 기능이 적용되지 않은 경우 트랜잭션 롤백은 발생하지 않습니다. 이를 확인하기 위해 Main 메서드에서 프록시 대신 클래스를 직접 호출하도록 코드를 수정합니다.
프로젝트를 빌드하고 수행한 후, 데이터베이스에서 데이터가 추가되었음을 확인하십시요.
Advanced transactional component¶
NeoDEEX 기반 어플리케이션에서는 서버 로직을 구현할 때, 트랜잭션을 관리하고 비즈니스 로직을 구현하는 비즈니스 로직 계층과 트랜잭션에 참여하여 데이터베이스를 액세스하는 데이터 액세스 계층으로 나누어 구현합니다. 이를 통해 데이터 액세스 코드를 재사용하거나 데이터베이스의 변경에 대해 유연한 대처가 가능하기 때문입니다.
Fox Transactions 비즈니스 로직 계층을 위해 FoxBizBase
클래스를 제공하며 데이터 액세스 계층을 위해 FoxDacBase
클래스를 제공합니다. FoxBizBase
클래스는 기본적으로 TransactionOptions.Required
설정이 되어 있으며 트랜잭션을 관리하는 트랜잭션 컨트롤러에 대한 지원 기능을 포함합니다. FoxDacBase
클래스는 데이터베이스 액세스를 위해 FoxDbAccess
객체의 자동 생성과 데이터베이스 연결에 대한 자동 닫기 기능 등을 제공합니다. 이 두 클래스는 FoxComponentBase
클래스에서 직/간접적으로 파생되었기 때문에 Fox Transactions 기능을 모두 제공합니다.
Adding DAC component¶
Note
DAC 은 Data Access Component 의 약자 입니다.
이 예제에서는 앞서 TxComp
에서 작성한 코드를 FoxDacBase
에서 파생하도록 수정하여 보다 편리하게 트랜잭션을 관리하는 방법에 대해 살펴볼 것입니다.
-
DacComp
클래스를 추가 하고,FoxDacBase
클래스에서 파생되도록 코드를 추가 합니다. -
IDacComp
인터페이스를 정의하고,DacComp
클래스가 이 인터페이스를 다음과 같이 구현하도록 합니다.FoxDacBase
클래스는 컴포넌트의 메서드 호출 직전에 구성 설정의 디폴트 연결문자열을 사용하여FoxDbAccess
객체를 생성하고DbAccess
속성에 설정 합니다. 따라서DacComp
클래스의 메서드는FoxDbAccess
객체를 명시적으로 생성할 필요가 없습니다. 또한FoxDacBase
클래스는 메서드 종료 직후DbAccess
속성에 설정된FoxDbAccess
객체의 연결 상태를 확인하며 닫히지 않은 연결을 자동으로 닫습니다.Note
FoxDacBase
클래스는FoxTransactionAttribute
특성을 이미 다음과 같이 선언하고 있습니다. 따라서FoxDacBase
에서 파생된DacComp
클래스 역시 트랜잭션 옵션으로Supported
을 사용하게 됩니다.Supported
옵션은 이 클래스(메서드)가 호출되기 전에 트랜잭션이 시작되었다면 그 트랜잭션에 참여(enlist)합니다. 만약 트랜잭션이 시작되지 않았다면 트랜잭션과 무관하게 코드가 수행됩니다. 트랜잭션은 비즈니스 로직 계층에서 관리하기 때문에 데이터 액세스 계층에 알맞은 트랜잭션 옵션입니다.
Adding Biz component¶
BIZ 컴포넌트는 비즈니스 로직을 구현하고 트랜잭션을 관리하는 컴포넌트 입니다. BIZ 컴포넌트를 위해 Fox Transactions 은 FoxBizBase
클래스를 제공합니다. 이 클래스는 기본적으로 FoxTransactionAttribute
특성이 명시되어 있으며 트랜잭션 옵션으로 Required
를 사용하여 트랜잭션을 사용합니다.
-
BizComp
클래스를 추가하고FoxBizBase
클래스에서 파생되도록 코드를 추가 합니다. -
IBizComp
인터페이스를 정의하고,BizComp
클래스가 이 인터페이스를 다음과 같이 구현하도록 합니다.BizComp
클래스의InsertData
메서드는DacComp
객체를 생성하고CreateExecution<T>
메서드를 호출하여 트랜잭션이DacComp
클래스까지 전달될 수 있도록 수행 문맥을 구성합니다.BizComp.InsertData
메서드는Required
옵션을 사용하고DacComp.InsertData
메서드는Supported
옵션을 사용하기 때문에,BizComp.InsertData
메서드에서 트랜잭션이 시작되고 이 트랜잭션은DacComp.InsertData
로 전달되어 트랜잭션 내에서 데이터 추가가 수행됩니다. -
Main
메서드에서BizComp
의InsertData
메서드를 호출하도록 코드를 다음과 같이 수정합니다.위 코드는 3개의 데이터를 추가하는 코드이며 3개의 데이터 추가는 하나의 트랜잭션 내에서 수행됩니다. 즉 3개의 데이터 추가를 모두 성공하거나 추가 도중 오류가 발생하는 경우에는 롤백되어 하나도 추가되지 않게 됩니다.
-
(Optional) 트랜잭션을 확인하기 위해 기존에 추가된 데이터를 모두 삭제하고,
Main
메서드의 코드를 다음과 같이 수정하고 프로젝트를 수행해 봅시다.프로그램은 중복 키 오류로 인해 예외를 발생하게 됩니다. 데이터베이스에서
TxTestTable
테이블의 내용을 조회(SELECT)해 보면 데이터가 존재하지 않습니다. 트랜잭션 롤백으로 인해 오류 발생 전에 추가된 데이터들이 롤백되었기 때문입니다.만약, Fox Transactions 의 수행 문맥을 사용하지 않고 다음과 같이
InsertData
메서드를 직접 호출하는 경우,동일하게 중복 키 오류가 발생하지만 오류 발생 전에 추가된 2개의 데이터가 테이블에 남아 있게 됩니다. 즉, 트랜잭션이 적용되지 않습니다.
Summary¶
Fox Transactions 은 수행 문맥을 통해 트랜잭션을 자동으로 생성하고 시작하며 오류 발생 여부에 따라 트랜잭션을 커밋하거나 롤백해 줍니다. 이를 통해 개발자는 트랜잭션 처리에 신경쓰지 않고 비즈니스 로직과 쿼리 작성에 집중할 수 있습니다. Fox Transactions 는 높은 개발 생산성 하에서 트랜잭션 기반 어플리케이션을 작성할 수 있도록 해 줍니다.