Dapper + Oracle + TransactionScope = 트랜잭션이 중단되었습니다.

c# dapper odp.net transactionscope

문제

나는 주변을 둘러 보았지만 우리가 가지고있는 문제를 해결하는 방법에 대해 적절한 (또는 만족스러운) 것을 찾지 못했습니다.

나는 Dapper와 ODP.NET 12 Managed 드라이버를 사용합니다. TransactionScope를 사용하지 않으면 문제가 발생하지 않습니다.

트랜잭션 범위에서 명령을 수행 할 때 throw되는 TransactionAbortedException을 통해 "Transaction has aborted"오류가 발생합니다.

관찰 된 행동 :

1) TransactionAbortedException은 트랜잭션이 완료되고 TransactionScope가 삭제 된 경우에만 throw됩니다. 예외가 발생하는 시점은 처리 중에 있습니다.

2) 예외적 인 경우에도 트랜잭션 개념이 실제로 작동합니다! Complete ()가 호출 된 후 변경 사항이 데이터베이스에 커밋됩니다.

아래는 코드 스 니펫입니다.

// Conn string: "Data Source=OraDB;Persist Security Info=True;User ID=userxxx;Password=passwordxxx;"   providerName="Oracle.ManagedDataAccess.Client
// Note: GetDbFactory().Create() returns a DbConnection object
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }))
using (var dbConn = GetDbFactory().Create())
{
    foreach (MyDTO dto in dtoList)
    {
        var tableDAO= new TableDAO(dbConn);
        MyEntity entity = new MyEntity()
        {
            Field1 = dto.Field1,
            Field2 = dto.Field2
        };
        tableDAO.AddOrUpdate(entity);
     }
     // Commit changes
     scope.Complete();
}

// This method is under the DAO class
public void AddOrUpdate(MyEntity entity)
{
    // Verify arguments
    entity.AsArgumentThrowExceptionIfNull("entity");
    // build param

    OracleDynamicParameters parameters = new OracleDynamicParameters();

    parameters.Add("P_FIELD1", entity.Field1);
    parameters.Add("P_FIELD2", entity.Field2);

    // execute SP
    dbConnection.Execute("PRC_MY_ENTITY_ADDORUPDATE", parameters, commandType: CommandType.StoredProcedure);
}//-- end AddOrUpdate()

========================================================================================================== ==============
업데이트 (2009 년 4 월 9 일)

필자는 오라클에게 접근 방식을 변경하고 다음 패턴을 사용합니다. 우리 코드는 오라클과 SQL Server 모두에서 연결을 처리하므로 코드 패턴이 일관성있는 패턴을 선호하지만 Oracle + TransactionScope를 사용하여 솔루션을 찾을 때까지 Oracle 명령 실행을 위해 아래 패턴을 사용합니다.

using (var dbConnection = dbConnFactory.Create())
{
    // Open db connection
    dbConnection.Open();
    using (var trans = dbConnection.BeginTransaction())
    {
        bool isSuccess = false;
        try
        {
             // Perform DB operations here
             trans.Commit();
             isSuccess = true;
        }
        finally
        {
             if(!isSuccess) trans.Rollback();
        }
   }
}

수락 된 답변

BeginTransaction ()을 최종 접근 방식으로 사용하고 있습니다. (원래 게시물에서 내 업데이트를 참조하십시오.) TransactionScope ()가 실패한 이유에 대해 자세히 읽었습니다.

1) ODP.Net은 Oracle 10g 이하 ( 소스 )에 연결할 때 단일 DB 연결을 사용하는 경우에도 분산 트랜잭션을 지원합니다. 내가 연결하는 데이터베이스는 실제로 10g입니다.

2) Oracle MTS Service가 설치되어 있어야합니다. 이것은 내 dev 컴퓨터에 설치하지 않았다.


인기 답변

나는 그 코드에 아무런 문제가 보이지 않는다. 그러나 해당 루프가 충분히 길면 트랜잭션이 시간 초과됩니다. 다음에 데이터베이스에 대해 작업 할 때 문제의 예외가 발생합니다. 시간 초과를 늘리려고 시도합니다 - Timeout은 TransactionScopeOption 클래스의 속성입니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.