2012-05-12 2 views
2

Я хочу, чтобы родительский объект удалял себя, и это дочерний объект в одном транзакционном устройстве. Я также хочу проверить оба случая, если объект для удаления существует, и если пользователь имеет права на объект. Рассмотрим следующий код:C# Transactionscope - вставить/выбрать в той же транзакции, несколько подключений

Я получаю MSDTC на сервере, исключая исключение. Есть ли способ передать соединение через мои методы обслуживания?

Пожалуйста, смотрите пример ниже:

// классы полета, FlightService, FlightDao // классы Pilot, 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. Являются ли пилоты и полеты в разных базах данных или с использованием разных строк соединения? Быстрое исправление заключается в том, чтобы включить 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. 
... 
Смежные вопросы