2

親オブジェクトがそれ自体を削除し、それが単一のトランザクションスコープ内の子オブジェクトになるようにしたい。また、削除するオブジェクトが存在するかどうか、およびユーザーがオブジェクトに対する権限を持っているかどうかを両方の場合に確認したいと思います。次のコードを検討してください。

サーバー上のMSDTCが利用できないという例外が発生します。とにかく私のサービスメソッドを介して接続を渡すことはありますか?

以下の例を参照してください。

//クラスFlight、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();   
        }
    }       
}
4

2 に答える 2

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;
}
于 2012-05-22T15:15:58.043 に答える
0

トランザクションで複数のデータ コンテキスト レイヤーを使用しています。互いに渡す必要があります。「deletePilot」呼び出しは、同じデータ コンテキスト内で実行する必要があります。1 つの解決策は、別のデータ サービスからのデータ コンテキストを受け入れるために、データ アクセス レイヤーにコンストラクターを配置することです。それらは同じコンテキストで操作を実行します。

public void deleteFlight(IYourDataContext context, Pilot pilot) {
PilotDao pilotDao = new PilotDao(context);
//do operations now in same context.
...
于 2012-05-15T04:31:24.263 に答える