【问题标题】:C# Transactionscope - insert/select in same transaction, multiple connectionsC# Transactionscope - 在同一个事务中插入/选择,多个连接
【发布时间】:2012-05-12 21:32:11
【问题描述】:

我想让一个父对象删除自己,它是单个事务范围中的子对象。我还想在这两种情况下检查要删除的对象是否存在,以及用户是否有权访问该对象。考虑以下代码:

我得到服务器上的 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();   
        }
    }       
}

【问题讨论】:

  • 你能把抛出异常的DAO的代码贴出来吗?
  • 我很好奇为什么这会试图升级为 DTC 交易。飞行员和航班是在不同的数据库上,还是使用不同的连接字符串?快速解决方法是在您的 Web 服务器上启用 DTC,但 DTC 事务非常昂贵,最好使用本机 SQL 事务。
  • 是的,谢谢你们的及时回复!我将使用 DAO 实现和错误编辑原始帖子。

标签: c# transactionscope msdtc


【解决方案1】:

您正在对事务使用多个数据上下文层。您需要将一个传递给另一个。 “deletePilot”调用应该在相同的数据上下文中执行。一种解决方案是在数据访问层使用构造函数来接受来自另一个数据服务的数据上下文。他们将在相同的上下文中执行操作。

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

【讨论】:

    【解决方案2】:

    这里的问题是我试图在同一个循环中多次使用同一个 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-07-16
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多