Transaction Processing (.NET)
목 차
1. Processing Transactions (개요)
2. Transaction Processing Fundamentals
2.1 ACID Properties
2.2 Transaction Boundaries
2.3 Distributed Transaction
3. Transaction Models
3.1 Manual Transaction
transaction processing.doc
3.1.1 Manual Transactions and ADO.NET
3.1.2 Manual Transactions and MSMQ
3.2 Automatic Transaction
3.2.1 Automatic Transaction Processing
3.2.2 Automatic Transactions and ASP.NET
3.2.3 Automatic Transactions and .NET Framework Classes
3.2.4 Automatic Transactions and Web Services
3.2.5 Voting in an Automatic Transaction
1. Processing Transaction (개요)
트랜잭션은 트랜잭션 단위내의 모든 operation이 성공적으로 수행되지 않으면 data-oriented resource가 결코 업데이트 되지 않는 것을 보장한다. 관련된 operation을 완전성공 또는 완전실패의 unit에 조합함으로써 에러복구를 간단히 하고 어플리케이션의 신뢰성을 향상시킨다.
Microsoft .NET Framework하에서의 트랜잭션 처리에 관한 사항과 일반적인 트랜잭션 처리에 대한 사항을 알아보자.
2. Transaction Processing Fundamentals
(기본적인 트랜잭션 처리의 용어와 개념소개)
- 트랜잭션은 성공이나 실패의 단위로서 관련된 임무의 집합
- 트랜잭션은 commit 이나 abort 중에 하나이다.
- 트랜잭션은 여러 개의 수행을 같이 결합한다.
- 트랜잭션은 다양한 데이터 자원에 걸쳐 사용할 수 있다.
2-1. ACID properties
ACID는 Atomicity, Consistency, Isolation, Durability를 상징한다. 이러한 특성들은 transaction이 “all or none”을 보장하기 위해 디자인되어 있고 많은 변수가 포함될 경우 복잡성을 줄여준다.
- Atomicity : transaction은 작업의 한 단위이며, 단지 한번 실행되거나 또는 전혀 일어나지 않음을 나타낸다. (a unit of work)
- Consistency : 데이터는 transaction 처리 동안 형태나 단위가 변하지 않는다. (a unit of integrity)
- Isolation : transaction은 자신에 포함된 데이터를 처리하는 유일한 시스템처럼 작동한다. (a unit of isolation)
- Durability : fault tolerance 기능을 한다. 데이터가 commit 된 직후 시스템에 에러가 발생하더라도 데이터의 안전을 보장한다. (a unit of recovery)
2-2. Transaction Boundaries
transaction boundary는 트랜잭션의 범위를 한정한다. transaction boundary안의 object는 공통의 트랜잭션 식별자를 공유한다.
트랜잭션이 실행됨에 따라, 다양한 트랜잭션 인식 자원들이 트랜잭션내에 참여할 수 있다. 예를 들면 트랜잭션 영역내에서 어플리케이션이 데이터베이스에 연결되면, 트랜잭션은 그 자원으로 흘러간다. 그리고 transaction boundary는 데이터베이스 서버를 포함하는 것으로 확장된다. 또한 process와 computer에 걸쳐서 트랜잭션을 디자인 할 수 있다. 따라서 transaction boundary를 process와 computer 사이에서 일관성을 관리하는 추상관념이라 할 수 있다.
transaction boundary를 제어하는 것은 어플리케이션에서 선택한 transaction model (manual 또는 automatic) 에 따라 결정된다.
Manual transaction에서는 트랜잭션을 시작하고 끝내는 명백한 지시어와 함께 트랜잭션 영역을 제어한다. 하나의 트랜잭션 영역 안에 또 다른 트랜잭션을 시작할 수 있다. 이것을 nested transaction이라 한다. 상위 트랜잭션은 하위 트랜잭션이 모두 commit될 때까지 commit 되지 않는다.
Automatic transaction은 각 컴포넌트에서 선언된 attribute에서 따라서 트랜잭션 영역을 관리한다. 트랜잭션은 트랜잭션에 관계한다고 지시된 object로 흘러가고 트랜잭션 밖에서 실행된다고 지시된 object는 통과한다. 또한 Nested transaction을 사용할 수 없다.
2-3. Distributed Transactions
분산 transaction processing(TP) 시스템이란 분산 환경에서 트랜잭션이 이기종간의 트랜잭션 인식 자원을 확장,연결하는 것을 도와준다. 분산 TP 시스템의 지원으로 어플리케이션이 다음과 같이 다양한 활동상태로 트랜잭션 unit을 구성할 수 있다. - MSMQ에서 메시지를 가져오고, Microsoft SQL Server database에 메시지를 저장하고 Oracle Server database에서 메시지가 참고하고 있는 것을 삭제할 수 있다.
분산 TP 시스템은 몇 개의 상호 작용하는 entity로 구성되어 있다. 다음의 entity는 논리적이며, 같은 컴퓨터나 다른 컴퓨터에 존재할 수 있다.
- Transaction Processing (TP) Monitors
: 트랜잭션 인식 어플리케이션과 자원의 집합 사이에 있는 소프트웨어이다. OS 활동을 극대화 하고, 네트워크 커뮤니케이션을 간소화 하고, 잠재적으로 다양한 데이터 자원에 접근하는 다양한 어플리케이션에 접근하는 많은 클라이언트와 접속하게 한다.
Microsoft Windows 2000에서 TP monitor는 DTC이다.
- Transaction Managers
: 분산 트랜잭션에서 참여하는 자원은 각각 local transaction manager (TM)을 가지고 있다. 이것은 입력과 출력 트랜잭션을 추적한다. TM은 모든 트랜잭션 처리 함수를 조정하고 관리하지만 데이터를 직접관리 하지 않는다.
- Resource Managers
: resource manager는 시스템 서비스이다. 지속적이고 영속적으로 데이터와 message queue를 관리하고 트랜잭션 파일 시스템을 관리한다. Resource manager는 데이터를 저장하고 재난 복구를 수행한다.
- Resource Dispensers
: resource dispenser는 공유되어 있는 비영속 상태를 관리한다. 예를 들어 ODBC resource dispenser는 더 이상 필요하지 않는 커넥션을 재사용하는 데이터베이스 커넥션 pool을 관리한다.
3. Transaction Models
automatic transaction에 관련된 .NET Framework object에서, .NET Framework class는 Windows 2000 Component Service에 등록해야 한다. 그러나 모든 transaction이 다 automatic인 것은 아니다.
3.1 Manual Transactions
ADO, OLE DB, ODBC, MSMQ에서 manual transaction 프로세싱을 가능하다. 명확하게 트랜잭션을 시작하고, 각 커넥션과 자원의 제어하고, 트랜잭션의 결과(commit 또는 abort)를 결정하고, 트랜잭션을 끝낸다. 이 모델은 트랜잭션에 대한 기준 control을 제공하지만 automatic control model에 포함된 간편한 구조생성이 없다. 예를 들면, 자동 enlistment가 없고, 데이터 저장에서의 coordination이 없다. 또한 트랜잭션이 object에서 object로 흘러가지 않는다.
분산 트랜잭션을 수동으로 제어하기 위해서는 recovery, concurrency, security, integrity 를 관리해야 한다. 즉, 트랜잭션 처리와 관련된 ACID 속성을 유지하기 위해 모든 프로그래밍 기술이 지원되어야 한다.
3.1.1 Manual Transactions and ADO.NET
SQL client 와 OLE DB .NET provider는 common language runtime에서 manual transaction을 지원한다.
두개의 provider는 database connection을 생성하고 트랜잭션을 시작하고 commit하거나 roll back 하는 관리된 object를 포함한다.
ADO.NET 트랜잭션은 전적으로 데이터베이스 안에서 처리되며, Microsoft Distributed Transaction Coordinator(DTC)나 다른 트랜잭션 메커니즘을 지원하지 않는다.
예) transaction 수행
트랜잭션은 논리적인 작업 단위로 묶이는 데이터베이스 동작의 그룹이다. 그리고 시스템에서 일어날 지 모르는 에러에도 불구하고 각 데이터베이스의 consistency와 integrity를 유지하고 제어하는 데 사용된다.
예를 들어서 자금이 하나의 계좌에서 다른 계좌로 이체된다고 할 경우, 한 계좌에는 금액이 빠져나가고, 다른 계좌에 같은 금액만큼 동시에 들어온다. 컴퓨터가 정전이 되거나, 네트워크가 불통되는 등 작동하지 않을 경우 때문에, 하나의 테이블에서 로우가 업데이트 되지만 관계된 테이블에 안 될 경우가 발생한 가능성이 있다. 만약 데이터베이스가 트랜잭션을 지원한다면, 이러한 사태에 대한 결과로 발생하는 데이터베이스의 불일치를 방지하기 위하여 데이터베이스 작업을 트랜잭션으로 그룹지어야 한다.
트랜잭션에 대한 3가지 기본 명령어가 있다. BEGIN, COMMIT, ROLLBACK.
BEGIN 명령어는 트랜잭션의 시작을 알린다. BEGIN 명령어 다음의 모든 procedure는 트랜잭션의 부분으로 간주되고 COMMIT 명령어에 의해 종결되거나, ROLLBACK 명령어에 의해 취소된다.
다음의 예를 Transaction-SQL을 사용한 트랜잭션 로직을 보여준다.
BEGIN TRAN
INSERT INTO account (account, amount, debitcredit) values (100, 100, ‘d’)
INSERT INTO account (account, amount, debitcredit) values (300, 100, ‘d’)
IF (@@ERROR > 0)
ROLLBACK
ELSE
COMMIT
ADO.NET에서 Connection과 Transaction객체를 이용하여 트랜잭션을 제어한다.
트랜잭션 실행방법
1. 트랜잭션의 시작을 알리기 위해 Connection 객체의 BeginTransaction 메쏘드를 호출한다.
2. 요구되는 SQL 문장을 실행한다.
3. 트랜잭션을 완료하기 위해 Transaction 객체의 Commit 메쏘드를 호출하거나,
트랜잭션을 취소하기 위해 Rollback 메쏘드를 호출한다.
SqlConnection myConnection = new SqlConnection("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI;");
myConnection.Open();
// Start a local transaction.
SqlTransaction myTrans = myConnection.BeginTransaction();
// Assign a transaction object for a pending local transaction.
SqlCommand myCommand = new SqlCommand();
myCommand.Transaction = myTrans;
try
{
myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
myCommand.ExecuteNonQuery();
myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
myCommand.ExecuteNonQuery();
myTrans.Commit();
Console.WriteLine("Both records are written to database.");
}
catch(Exception e)
{
myTrans.Rollback();
Console.WriteLine(e.ToString());
Console.WriteLine("Neither record was written to database.");
}
finally
{
myConnection.Close();
}
주의 : DataSet 객체는 AcceptChanges 와 RejectChanges 메쏘드를 사용하는 Commit 모델을 가진다. 그러나 이 모델은 데이터베이스에 영향을 미치지 않고 단지 DataSet의 데이터가 있는 캐시에 영향을 미친다.
3.1.2 Manual Transactions and MSMQ
관리 언어로 작성된 component는 MSMQ에서 메시지를 보내거나 받을 수 있다.
MSMQ는 어플리케이션에서 message queuing을 실행하는 기술이다. MSMQ로 메시지 queue들을 생성하거나 삭제할 수 있고, 메시지를 보내거나 받을 수 있고, 관리할 수 있다. 트랜잭션은 MSMQ의 비동기 능력을 요구하는 enterprise 시스템에서 중요한 부분이다.
공통언어런타임은 MessageQueueTransaction Class를 통해서 manual transaction을 지원한다. MSMQ transaction은 전적으로 MSMQ 엔진 내에서 다루어진다.
3.2 Automatic Transactions
Microsoft Transaction Server(MTS), COM+ 1.0, 그리고 common language runtime은 동일한 automatic distributed transaction model을 지원한다. ASP.NET 페이지, Web Service method 또는 .NET Framework class가 transaction에 관계한다고 표시되면, 트랜잭션의 영역내에서 자동적으로 실행된다. 페이지, 웹서비스 method, 또는 class내의 트랜잭션 attribute 값을 셋팅하면 객체의 트랜잭션 행위를 제어할 수 있다. Attribute 값은 생성된 객체의 트랜잭션 행위를 결정한다. 따라서 선언된 attribute 값에 따라서 객체는 현재의 또는 다가올 트랜잭션에 관계하거나, 새로운 트랜잭션의 루트가 되거나, 트랜잭션에 전혀 관계하지 않을 수 있다. 트랜잭션 attribute 선언 구문은 .NET Framework class, ASP.NET page, 그리고 웹 서비스 method에서 조금씩 차이가 있다.
선언된 트랜잭션 attribute는 트랜잭션에 객체를 관련하는 방법을 설정하고, 프로그램적으로 구성된다. 비록 이 선언된 수준이 트랜잭션의 logic을 표현하지만, 이것은 물리적인 트랜잭션으로부터 제거된 하나의 스텝이다. 물리적인 트랜잭션은 트랜잭션 객체가 데이터베이스나 message queue와 같은 데이터 자원에 접근할 때 일어난다. 객체와 관련된 트랜잭션은 자동으로 적절한 자원관리자로 흘러간다. OLE DB, ODBC, ADO와 같은 관련된 driver는 객체의 문맥에서 트랜잭션을 찾고 DTC를 통해서 트랜잭션에 요청한다.
3.2.1 Automatic Transaction Processing
Automatic Transaction Processing은 런타임시 트랜잭션에 관계시키기 위해 디자인 타임에서 클래스를 구성할 수 있게 하는 COM+에 의해 제공되는 서비스이다. 이 서비스를 사용하기 위해서 클래스는 System.EnterpriseServices.ServicedComponent class로부터 직, 간접적으로 상속되어져 있어야 한다.
3.2.2 Automatic Transaction and ASP.NET
ASP.NET은 Microsoft Windows 2000이 작동하는 시스템에서 automatic transaction을 지원한다. ASP.NET page에 트랜잭션 지시어를 삽입하여서 그 page가 기존의 트랜잭션에 관계하거나, 새로운 트랜잭션을 시작하거나, 또는 트랜잭션의 참여에 배제하는 것을 지시할 수 있다.
다음의 table은 ASP.NET에서 사용할수 있는 트랜잭션 지시어를 나타낸다.
지시어 |
설 명 |
Disabled |
ASP.NET은 트랜잭션 문맥을 무시한다. 트랜잭션 상태의 default이다. |
NotSupported |
페이지가 트랜잭션 영역내에서 동작하지 않는 것을 나타낸다. |
Supported |
페이지가 기존의 트랜잭션 문맥내에서 동작하는 것을 나타낸다.
트랜잭션이 존재하지 않으면, 페이지는 트랜잭션 없이 동작한다. |
Required |
페이지가 기존의 트랜잭션 문맥내에서 동작하는 것을 나타낸다.
트랜잭션이 존재하지 않으면, 페이지는 한번 시작한다. |
RequiresNew |
페이지에 트랜잭션을 필요하고 각 요청에 새로운 트랜잭션을 시작한다. |
코드내에 지시어를 넣어서 페이지가 지원하는 트랜잭션 레벨을 지시할 수 있다. 예를 들어, 다음의 지시어를 삽입하여 페이지 활동이 항상 트랜잭션 영역내에서 실행하는 것을 보증할 수 있다.
<%@ Page Transaction=”Required” %>
만약 트랜잭션 지시어를 생략하면 트랜잭션은 페이지 내에서 실행되지 않는다.
3.3.3 Automatic Transactions and .NET Framework Class
.NET Framework class의 개체는 automatic transaction에 관계할 수 있다. 예를 들어, 객체가 돈을 데이터베이스의 계좌로 보내기 위해 ADO.NET을 사용한다면 데이터베이스의 resource manager는 객체가 트랜젝션을 수행할 지를 결정한다. 그렇게 하여 그것은 자동적으로 데이터베이스에 기입된다.
Automatic transaction에 클래스를 관계시키기 위해 다음의 과정을 따른다.
1. 클래스에 TransactionAttribute 를 적용한다.
2. ServicedComponent 클래스를 상속받는다.
3. Sign the assembly with a strong name.
To sign the assembly using attributes create a key pair using the Sn.exe utility
Sn –k TestApp.snk
Add the AssemblyKeyFileAttribute or AssemblyKeyNameAttribute assembly attribute specifying the name of the file containing the key pair to sign the assembly with a strong name.
[assembly: AssemblyKeyFileAttribute("TestApp.snk")]
4. 클래스를 포함하고 있는 assembly를 COM+ catalog로 등록한다.
만약 클래스의 인스턴스를 호출하는 클라이언트가 common language runtime으로 관리되면 등록이 수행이다. 그러나 비관리 호출이 일어나면 수동으로 등록하기 위해서 .NET Services Installation Tool(Regsvcs.exe)를 사용하여라.
다음의 예제는 ServicedComponent 클래스를 상속받는 클래스에 TransactionAttribute를 적용하는 방법을 보여준다.
[Transaction(TransactionOption.Required)]
public class Bar() : ServicedComponent
{
// ……
}
transaction attribute를 적용할 때, Transaction, transaction, TransactionAttribute, transactionattribute 를 다 사용할 수 있다.
다음의 테이블은 각각의 생성자 변화의 리스트와 설명을 나타낸다.
Attribute value |
설 명 |
Disabled |
[Transaction(TransactionOption.Disabled)] |
NotSupported |
[Transaction(TransactionOption.NotSupported)] |
Supported |
[Transaction(TransactionOption.Supported)] |
Required (default) |
[Transaction(TransactionOption.Required)] |
RequiredNew |
[Transaction(TransactionOption.RequiredNew)] |
Sample Class
다음의 코드 예제는 automatic transaction의 몇 가지 요소를 보여준다. 이 예제에서 transaction 클래스와 클래스를 호출하는 클라이언트는 runtime에서 관리된다.
// -----------------------------------------------------------------
// TestApp.cs
// Generate a Strong name:
// sn -k TestApp.snk
// Compile the code:
// csc /target:exe /r:System.EnterpriseServices.dll TestApp.cs
// Run TestApp:
// start TestApp.exe
// -----------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
using System.EnterpriseServices;
using System.Reflection;
//Registration details.
//COM+ application name as it appears in the COM+ catalog.
[assembly: ApplicationName("TestApp")]
//Strong name for assembly.
[assembly: AssemblyKeyFileAttribute("TestApp.snk")]
[Transaction(TransactionOption.Required)]
public class Account : ServicedComponent
{
//Provides SetComplete behavior in the absence of exceptions.
[AutoComplete]
public void Debit(int amount)
{
// Do some database work. Any exception thrown here aborts the
// transaction; otherwise, transaction commits.
}
}
public class client
{
public static int Main()
{
Account accountX = new Account();
accountX.Debit(100);
return 0;
}
}
3.3.4 Automatic Transaction and Web Services
ASP.NET은 Web Forms 와 비슷하고 영속적인 추상관념을 프로그래밍에 사용하는, Web Service를 만들고 보여주는 미리 만들어진 지원을 사용한다. 결과적으로 확장성이 풍부한 모델이고, HTTP, XML, SOAP, WSDL 공개 인터넷 표준등을 포함한다. 이처럼 공개 표준을 지원하기 때문에, Web Service는 어떤 클라이언트나 인터넷이 가능한 장치로 접근하고 이용될 수 있다.
Web Service는 automatic transaction의 영역내에서 코드가 실행될 수 있는 옵션을 제공한다.
WebMethod attribute의 TransactionOption property를 사용하여 automatic transaction을 선언할 수 있다. TransactionOption property에 TransactionOption.RequiresNew 라고 설정하면 웹 서비스 클라이언트가 웹 서비스 메쏘드를 호출할 때 마다 새로운 트랜잭션을 시작한다.
아래의 예제는 DeleteAuthor라는 한 웹 서비스 메쏘드를 실행하는 서비스를 보여준다.
<%@ WebService Language="C#" Class="Orders" %>
<%@ assembly name="System.EnterpriseServices" %>
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.Services;
using System.Web.Util;
using System.EnterpriseServices;
public class Orders : WebService
{
[ WebMethod(TransactionOption=TransactionOption.RequiresNew)]
public int DeleteAuthor(string lastName)
{
String deleteCmd = "DELETE FROM authors2 where au_lname='" + lastName + "'" ;
SqlConnection sqlConn = new SqlConnection("user
id=sa;database=pubs;server=myserver");
SqlCommand myCommand = new SqlCommand(deleteCmd,sqlConn);
// If a Web Service method is participating in a transaction and an
// exception occurs, ASP.NET automatically aborts the transaction.
// Likewise, if no exception occurs, then the transaction is
// automatically committed.
myCommand.Connection.Open();
return myCommand.ExecuteNonQuery();
}
}
3.3.5 Voting in an Automatic Transaction
.NET Framework class와 ASP.NET 페이지는 현재 트랜잭션을 commit하거나 abort 하는 것을 제안한다. 코드상에 명백하게 정해주지 않으면 default로 commit 이 된다.
Default로 사용하는 commit은 각각의 트랜잭션이 자원을 release하는 시간을 길게 하기 때문에 어플리케이션의 성능을 저하한다.
AutoComplete 사용방법
System.EnterpriseServices.AutoCompleteAttribute 는 메쏘드가 정상적으로 리턴되다면 트랜잭션을 완결하는 편으로 객체를 트랜잭션에 관계시킨다. 만약 메쏘드가 예외를 발생시키면, 트랜잭션은 실패한다.
ServicedComponent 클래스를 상속받는 클래스에만 이 attribute를 적용시킬 수 있다.
클래스 메쏘드 앞에 이 attribute를 작성한다. 만약 인터페이스 메쏘드에 attribute를 더할 경우 CLR은 이것을 무시한다.
[Transaction(TransactionOption.Supported)]
public class Account : ServicedComponent {
[AutoComplete]
public void Debit(int amount) {
// Do some database work. Any exception thrown here aborts the transaction;
// otherwise, transaction commits.
}
}
SetAbort 와 SetComplete 사용방법
System.EnterpriseServices.ContextUtil 클래스를 사용하여 명백하게 트랜잭션을 commit 하거나 abort 할 수 있는 SetComplete 와 SetAbort 메쏘드를 이용할 수 있다.
//Try to do something crucial to the transaction in progress.
if( !DoSomeWork() )
{
//Something goes wrong.
ContextUtil.SetAbort();
}
else
{
//All goes well.
ContextUtil.SetComplete();
}