/// <summary> /// ASP.NET에서 페이지 또는 XML Web services 같은 이벤트 처리기의 실행을 시작하기 바로 전에 발생하는 Event에 대한 Handler<br/> /// 1. Application 생성 시 한번만 IoC 관련 정보를 초기화 합니다.<br/> /// 2. UnitOfWork를 Start 시킵니다. /// </summary> /// <remarks> /// 기본 설정 파일이 아닌 다른 파일에 대해 초기화를 하려면 재정의를 해야 한다. /// </remarks> protected override void OnBeginRequest(object sender, EventArgs e) { base.OnBeginRequest(sender, e); if (NeedStartUnitOfWork() == false) { if (HttpContext.Current != null) { if (IsDebugEnabled) { log.Debug("Unit of Work를 시작할 필요가 없는 단순 파일 요청이므로, UnitOfWork를 시작하지 않습니다!!! RawUrl=[{0}]", HttpContext.Current.Request.RawUrl); } } return; } //lock(_syncLock) { bool loadedConversation = false; // Session이 사용 가능하다면, 저장된 IUnitOfWork 객체가 있는지 확인한다. if (IsAspSessionAvailable) { if (IsDebugEnabled) { log.Debug("ASP.NET Session is available. Retrieve instance of IUnitOfWork from ASP.NET Session."); } loadedConversation = LongConversationManager.LoadConversation(); } if (loadedConversation == false) { if (UnitOfWork.IsNotStarted) { UnitOfWork.Start(); if (IsDebugEnabled) { log.Debug("UnitOfWork를 시작했습니다!!!"); } } } } }
/// <summary> /// 지정된 함수를 현재 UnitOfWork의 Transaction 하에서 수행합니다. /// </summary> /// <typeparam name="T">Return Type of Function to execute</typeparam> /// <param name="transactionalFunc">Function to execute under Transaction</param> /// <param name="isolationLevel">격리수준</param> /// <param name="nestingOptions">UnitOfWork Nesting option.</param> /// <returns>함수 수행 결과</returns> public static T Transaction <T>(Func <T> transactionalFunc, IsolationLevel isolationLevel, UnitOfWorkNestingOptions nestingOptions) { transactionalFunc.ShouldNotBeNull("transactionalFunc"); if (IsDebugEnabled) { log.Debug("Execute the specified action under transaction... " + "transactionalFunc=[{0}], isolationLevel=[{1}], nestingOptions=[{2}]", transactionalFunc, isolationLevel, nestingOptions); } // 기존 UnitOfWork에 참여할 수도 있고, 새로운 UnitOfWork를 생성할 수도 있습니다. // using (UnitOfWork.Start(nestingOptions)) { // 기존 Transaction 이 없다면, 새로운 Transaction 에서 작업합니다. // if (UnitOfWork.Current.IsInActiveTransaction == false) { if (IsDebugEnabled) { log.Debug("새로운 NHibernate.ITransaction을 생성합니다."); } var tx = UnitOfWork.Current.BeginTransaction(isolationLevel); try { var result = transactionalFunc(); tx.Commit(); if (IsDebugEnabled) { log.Debug("Transactional Function을 수행하고, Transaction.Commit을 수행하였습니다!!!"); } return(result); } catch (Exception ex) { if (log.IsErrorEnabled) { log.Error("Fail to execute transactional action. rollback transaction."); log.Error(ex); } tx.Rollback(); throw; } finally { if (tx != null) { tx.Dispose(); if (IsDebugEnabled) { log.Debug("Dispose current transaction."); } } } } if (IsDebugEnabled) { log.Debug("활성화된 기존 Transaction에 참여하여, 실행합니다."); } return(transactionalFunc.Invoke()); } }
/// <summary> /// 지정된 <see cref="Action"/>를 지정된 격리수준의 Transaction 하에서 수행한다. /// </summary> /// <param name="isolationLevel">격리수준</param> /// <param name="transactionalAction">Action to execute under Transaction</param> /// <param name="nestingOptions">UnitOfWork Nesting option.</param> public static void Transaction(IsolationLevel isolationLevel, Action transactionalAction, UnitOfWorkNestingOptions nestingOptions) { transactionalAction.ShouldNotBeNull("transactionalAction"); if (IsDebugEnabled) { log.Debug("Execute the specified action under transaction... " + "isolationLevel=[{0}], transactionalAction=[{1}], nestingOptions=[{2}]", isolationLevel, transactionalAction, nestingOptions); } using (UnitOfWork.Start(nestingOptions)) { // if we are already in a transaction, don't start a new one if (UnitOfWork.Current.IsInActiveTransaction) { if (IsDebugEnabled) { log.Debug("활성화된 기존 Transaction에 참여합니다."); } transactionalAction(); } else { if (IsDebugEnabled) { log.Debug("새로운 NHibernate.ITransaction을 생성합니다."); } var tx = UnitOfWork.Current.BeginTransaction(isolationLevel); try { transactionalAction(); tx.Commit(); if (IsDebugEnabled) { log.Debug("Transactional Action을 수행하고, Transaction.Commit을 수행하였습니다."); } } catch (Exception ex) { if (log.IsErrorEnabled) { log.Error("Fail to execute transactional action. rollback transaction."); log.Error(ex); } tx.Rollback(); throw; } finally { if (tx != null) { tx.Dispose(); if (IsDebugEnabled) { log.Debug("Dispose current transaction."); } } } } } }