17. SqlTransaction 클래스 / TransactionScope 클래스
.NET프로그래밍/ADO.NET 2009. 9. 28. 11:42 |트랜잭션 처리 - 한번에(버튼 한번 클릭으로) 여러 개의 CRUD를 처리
Update문
Delete문
-------------------------------------------------------------------------------------
==> [FrmSqlTransaction.aspx] 소스 및 디자인
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="FrmSqlTransaction.aspx.cs" Inherits="FrmSqlTransaction" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnCommand" runat="server" Text="업데이트 및 삭제"
onclick="btnCommand_Click" />
<asp:Button ID="btncmdCommand" runat="server" Text="삭제+삭제"
onclick="btncmdCommand_Click" />
<br />
<asp:Label ID="lblError" runat="server" ForeColor="Red"></asp:Label>
</div>
</form>
</body>
</html>
-------------------------------------------------------------------------------------
==> [FrmSqlTransaction.aspx.cs]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Data.SqlClient;
using System.Transactions;
public partial class FrmSqlTransaction : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnCommand_Click(object sender, EventArgs e)
{
string updateQuery =
"Update Categories Set CategoryName = '노트북' Where CategoryID = 19";
string deleteQuery =
"Delete Categories Where CategoryID >= 20";
using (SqlConnection con = new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
con.Open();
//[1] SqlTransaction 클래스의 인스턴스 생성
SqlTransaction tran = con.BeginTransaction(); // 트랜잭션 걸기, 괄호안에 이름(별칭)줄 수도 있다.
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.Transaction = tran; //[2] 현재 명령어에서 사용할 트랜잭션 지정
try
{
cmd.CommandText = updateQuery;
cmd.ExecuteNonQuery(); // 수정
cmd.CommandText = deleteQuery;
cmd.ExecuteNonQuery(); // 삭제
tran.Commit(); // [3] 에러가 발생하지 않으면 커밋
lblError.Text = "정상 처리";
}
catch (Exception ex)
{
lblError.Text = ex.Message; // 에러메시지 출력
tran.Rollback(); //[4] 에러가 발생하면 롤백
}
}
}
// 트랜잭션 처리하는 2번째 방법
protected void btncmdCommand_Click(object sender, EventArgs e)
{
string updateQuery =
"Delete Categories Where CategoryID = 7";
string deleteQuery =
"Delete Categories Where CategoryID2 = 9";
// "참조추가"에서 - > .NET -> System.Transactions 추가
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection con = new SqlConnection(
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
try
{
cmd.CommandText = updateQuery;
cmd.ExecuteNonQuery(); // 수정
cmd.CommandText = deleteQuery;
cmd.ExecuteNonQuery(); // 삭제
lblError.Text = "정상 처리";
}
catch (Exception ex)
{
lblError.Text = ex.Message; // 에러메시지 출력
}
}
//scope.Complete(); // 완료...
}
}
}
/*
- SqlTransaction 클래스 - SQL Server 데이터베이스에 만들어질Transact-SQL 트랜잭션을 나타냅니다. 이 클래스는 상속될 수 없습니다.
응용 프로그램은 SqlConnection 개체의 BeginTransaction을 호출하여 SqlTransaction 개체를 만듭니다.
트랜잭션과 관련된 모든 후속 작업(예를 들어, 트랜잭션 커밋이나 중단)은 SqlTransaction 개체에서 수행됩니다.
참고) SqlTransaction을 커밋하거나 롤백할 때는 Try/Catch 예외 처리를 항상 사용해야 합니다. 연결이 종료되었거나 서버에서 트랜잭션이
이미 롤백된 경우 Commit과 Rollback은 모두 InvalidOperationException을 생성합니다.
*/
/*
- TransactionScope 클래스 - 트랜잭션 코드 블록을 만듭니다. 이 클래스는 상속될 수 없습니다.
System.Transactions 인프라는 Transaction 클래스 기반의 명시적 프로그래밍 모델과 TransactionScope 클래스를 사용하는 암시적 프로그래밍 모델을 둘 다 제공합니다.
후자의 경우 인프라에서 자동으로 트랜잭션을 관리합니다.
참고) 앰비언트 트랜잭션 컨텍스트가 자동으로 관리되도록 TransactionScope 클래스를 사용하여 암시적 트랜잭션을 만드는 것이 좋습니다.
또한 여러 함수 호출이나 여러 스레드 호출에 같은 트랜잭션을 사용해야 하는 응용 프로그램에는 TransactionScope 및 DependentTransaction 클래스를 사용해야 합니다.
*/
-------------------------------------------------------------------------------------
[실행결과]
--> (트랜잭션)실행하기 전 [SQL Server] - [데이터베이스] - [Market데이터베이스]내의 [dbo.Categories]테이블의 화면.
--> 아래그림의 웹페이지에서 왼쪽에 있는 버튼인 "업데이트 및 삭제"를 누르면 버튼아래에 있는 레이블에서 빨간색 글씨로 "정상 처리"라고 출력되며, [dbo.Categories]테이블의 "CategoryID"가 19번인 데이터의 "CategoryName"이 "컴퓨터"에서 "노트북"으로 수정(Update)되고, "CategoryID"가 20번 이상인 데이터들이 [dbo.Categories]테이블에서 삭제된다.(위에 있는 [FrmSqlTransaction.aspx.cs]코드에서 "btnCommand_Click"이벤트핸들러 코드의 "updateQuery문"과 "deleteQuery문"을 둘다 만족하므로 '에러'가 나지 않고 정상적으로 '업데이트'와 '삭제'가 실행되는 것이다.(= tran.Commit();))
--> [dbo.Categories]테이블에서 "CategoryID"가 19번인 데이터의 "CategoryName"이 "컴퓨터"에서 "노트북"으로 수정(Update)되었고, "CategoryID"가 20번 이상인 데이터들이 [dbo.Categories]테이블에서 삭제되었다.
--> 아래그림의 웹페이지에서 오른쪽에 있는 버튼인 "삭제+삭제"를 누르면 버튼아래에 있는 레이블에서 빨간색 글씨로 "열 이름 'CategoryID2'이(가) 잘못되었습니다."라고 "에러 메시지"가 출력되며, [dbo.Categories]테이블에서 "CategoryID"가 7번인 데이터와 9번인 데이터 둘다 삭제되지 않고 원래상태대로 존재한다. 이는 [FrmSqlTransaction.aspx.cs]코드의 "btncmdCommand_Click"이벤트핸들러 코드에서 "updateQuery문(CategoryID = 7)"은 만족하지만, "deleteQuery문(CategoryID2 = 9)"은 만족하지 않으므로, 결국 하나도 실행되지 않고 모두 "RollBack Tran"되는 것이다. 참고로 "TransactionScope 클래스"는 "Begin Tran / Commit Tran / RollBack Tran"의 기능을 모두 내장하고 있다.)
--> 아래그림의 [dbo.Categories]테이블에서 "CategoryID"가 7번인 데이터와 9번인 데이터 둘다 삭제되지 되지 않고, 원래상태대로 존재하는 것을 볼 수 있다.
'.NET프로그래밍 > ADO.NET' 카테고리의 다른 글
19. DataTable 클래스 (0) | 2009.09.28 |
---|---|
18. DataSet 클래스 (0) | 2009.09.28 |
16. 수정(Modify) / 삭제(Delete) (0) | 2009.09.28 |
[참고] 비동기실행(BeginExecuteNonQuery) - 다중 처리 (0) | 2009.09.28 |
15. 상세보기 (0) | 2009.09.28 |