2012-05-12 40 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. 
...