[C# PL/SQL] 7.C# 애플리케이션에서 오라클 프로시저를 이용한 트랜잭션 관리, COMMIT, ROLLBACK, 트랜잭션의 시작과 끝 처리.

본 글에서는 C# 애플리케이션에서 Oracle의 ProC를 이용하여 트랜잭션을 관리하는 방법을 깊이 있게 설명하겠습니다. 우리는 트랜잭션의 시작과 끝 처리, COMMITROLLBACK의 개념을 다루고, 실제 코드 예제를 통해 각 단계를 이해하도록 하겠습니다.

1. 트랜잭션 관리의 중요성

트랜잭션 관리란 여러 데이터베이스 작업을 하나의 논리적 단위로 묶어서 처리하는 것을 말합니다. 이는 데이터 무결성을 보장하고, 오류 발생 시 데이터 손실을 예방하는데 중요합니다. 트랜잭션은 ACID(Atomicity, Consistency, Isolation, Durability) 속성을 따라야 합니다.

  • Atomicity: 트랜잭션의 모든 작업이 성공적으로 완료되거나 전부 실패해야 함을 보장합니다.
  • Consistency: 트랜잭션이 수행되기 전과 후의 데이터베이스 상태가 일관되도록 유지합니다.
  • Isolation: 동시에 실행되는 트랜잭션이 서로의 영향을 미치지 않도록 보장합니다.
  • Durability: 성공적으로 수행된 트랜잭션의 결과는 시스템 오류가 발생해도 유지되어야 합니다.

2. 오라클 프로시저와 C#

Oracle 프로시저는 데이터베이스에서 실행되는 저장 프로시저로, 복잡한 쿼리나 여러 단계의 작업을 일괄적으로 수행할 수 있습니다. C# 애플리케이션은 Oracle 데이터베이스와의 상호작용을 위해 Oracle Data Provider for .NET(OleDb 또는 ODP.NET)를 사용할 수 있습니다.

2.1 Oracle 프로시저 생성 예제

기본적인 오라클 프로시저의 예로, 사용자의 이름과 나이를 입력받아 데이터를 추가하는 프로시저를 만들어보겠습니다.

CREATE OR REPLACE PROCEDURE AddUser(
    p_name IN VARCHAR2,
    p_age IN NUMBER
)
AS
BEGIN
    INSERT INTO Users(name, age) VALUES(p_name, p_age);
END;

3. C#에서 Oracle 프로시저 호출하기

이제 C# 애플리케이션에서 이 프로시저를 호출하여 데이터 추가 작업을 수행하는 방법을 살펴보겠습니다.

using System;
using System.Data;
using Oracle.ManagedDataAccess.Client;

namespace OracleTransactionExample
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectionString = "User Id=your_username;Password=your_password;Data Source=your_data_source;";
            using (OracleConnection connection = new OracleConnection(connectionString))
            {
                connection.Open();
                OracleTransaction transaction = connection.BeginTransaction();

                try
                {
                    using (OracleCommand command = new OracleCommand("AddUser", connection))
                    {
                        command.CommandType = CommandType.StoredProcedure;

                        command.Parameters.Add("p_name", OracleDbType.Varchar2).Value = "John Doe";
                        command.Parameters.Add("p_age", OracleDbType.Int32).Value = 30;

                        command.ExecuteNonQuery();
                    }

                    // COMMIT 트랜잭션
                    transaction.Commit();
                    Console.WriteLine("사용자가 성공적으로 추가되었습니다.");
                }
                catch (Exception ex)
                {
                    // ROLLBACK 트랜잭션
                    transaction.Rollback();
                    Console.WriteLine("오류 발생: " + ex.Message);
                }
            }
        }
    }
}

4. 트랜잭션의 시작과 끝 처리

C#에서 Oracle 트랜잭션을 시작하고 종료하는 과정은 매우 간단합니다. 위의 예제에서 주문한 부분은 트랜잭션을 TRANSACTION 객체를 통해 관리합니다. 이 객체는 트랜잭션을 시작하고, 트랜잭션이 성공적으로 완료되면 COMMIT를 호출하여 변경 사항을 저장합니다. 반면에 에러가 발생할 경우 ROLLBACK을 호출하여 모든 변경 사항을 롤백합니다.

4.1 트랜잭션 상태 확인

트랜잭션의 상태를 체크하는 것은 트랜잭션 관리에 또 다른 중요한 포인트입니다. SQL에서 자주 사용되는 방법 중 하나는 SELECT를 사용하여 상태를 확인하는 것입니다.

using (OracleCommand command = new OracleCommand("SELECT COUNT(*) FROM Users", connection))
{
    int userCount = Convert.ToInt32(command.ExecuteScalar());
    Console.WriteLine($"현재 사용자 수: {userCount}");
}

5. 예외 처리와 로깅

트랜잭션 처리 중에 예외가 발생할 수 있으므로 적절한 예외 처리가 필요합니다. C#의 try-catch 블록을 사용할 수 있으며, 에러가 발생했을 때 시스템 관리자나 개발자가 문제를 파악할 수 있도록 로깅하는 것도 좋습니다.

catch (Exception ex)
{
    // Log error (예: 파일에 기록)
    File.AppendAllText("error.log", DateTime.Now + ": " + ex.Message + Environment.NewLine);
    transaction.Rollback();
    Console.WriteLine("오류 발생: " + ex.Message);
}

6. 성능 최적화

트랜잭션 관리는 성능에 영향을 미칠 수 있습니다. 필요 없는 트랜잭션은 피하고, 긴 트랜잭션은 작은 단위로 나누는 것이 효율적입니다. 프로시저 내에서 불필요한 데이터를 조회하거나 수정하는 것을 최소화해야 합니다.

7. 결론

Oracle 프로시저와 C#을 결합하여 강력한 트랜잭션 관리 기능을 구현할 수 있습니다. 트랜잭션의 시작과 끝 처리, COMMIT, ROLLBACK 및 예외 처리를 구현하는 과정은 안정적인 데이터베이스 애플리케이션 개발에 필수적입니다. 이러한 내용을 잘 이해하고 응용하여 더욱 효과적인 솔루션을 만들어 나가시기 바랍니다.

8. 참고 문헌