2012-05-12 33 views
2

我想有一個父對象刪除自己,它是一個事務中的子對象。我也想在兩種情況下檢查是否存在要刪除的對象,以及用戶是否有權訪問該對象。考慮下面的代碼:C#Transactionscope - 插入/選擇在同一個事務中,多個連接

我得到服務器上的MSDTC是不可用的異常。無論如何要通過我的服務方法傳遞連接嗎?

請看下面的例子:

//班航班,FlightService,FlightDao //類試點,PilotService,PilotDao

// FlightService 
public void deleteFlight(Flight flight) { 
    FlightDao flightDao = new FlightDao(); 
    Flight existingFlight = flightDao.findById(flight.Id); 
    if (existingFlight != null) { 
     using (TransactionScope scope = new TransactionScope()) { 
      try { 
       PilotService.Instance.deletePilot(flight.Pilot); 
       flightDao.delete(flight); 
      } catch (Exception e) { 
       log.Error(e.Message, e); 
       throw new ServiceException(e.Message, e); 
      } 
      scope.Complete(); 
     } 
    }  
} 

// PilotService 
public void deleteFlight(Pilot pilot) { 
    PilotDao pilotDao = new PilotDao(); 
    Pilot existingPilot = pilotDao.findById(pilot.Id); // THIS LINE RIGHT HERE THROWS EXCEPTION 
    if (existingPilot != null) { 
     using (TransactionScope scope = new TransactionScope()) { 
      try {    
       pilotDao.delete(pilot); 
      } catch (Exception e) { 
       log.Error(e.Message, e); 
       throw new ServiceException(e.Message, e); 
      } 
      scope.Complete(); 
     } 
    }  
} 
+0

你能請張貼在異常被拋出的在DAO的代碼? – MrJames

+0

我很好奇,爲什麼這是試圖升級到DTC交易。飛行員和航班是在不同的數據庫上,還是使用不同的連接字符串?快速修復是在Web服務器上啓用DTC,但DTC事務非常昂貴,最好使用本地SQL事務。 –

+0

是的,感謝您的及時回覆傢伙!我將使用DAO實現和錯誤編輯原始帖子。 –

回答

0

這裏的問題是我試圖在同一個循環內多次使用相同的SqlDataReader。這絕對不適用於交易。

例子:

SqlCommand command = new SqlCommand(...); 
SqlDataReader reader = command.ExecuteReader(); 
if (reader.read()) { 
    return buildMyObject(reader); 
} 

private MyObject buildMyObject(SqlDataReader reader) { 
    MyObject o1 = new MyObject(); 
    // set fields on my object from reader 

    // broken! i was attempting create a new sql connection here and attempt to use a reader 
    // but the reader is already in use. 
    return o1; 
} 
0

您使用的是有多個交易數據上下文層。你需要將一個傳遞給另一個。 「deletePilot」調用應該在相同的數據上下文中執行。一種解決方案是讓數據訪問層的構造函數接受來自其他數據服務的數據上下文。他們將在相同的環境下執行操作。

public void deleteFlight(IYourDataContext context, Pilot pilot) { 
PilotDao pilotDao = new PilotDao(context); 
//do operations now in same context. 
...