代码之家  ›  专栏  ›  技术社区  ›  jac

SQL事务是如何工作的?

  •  2
  • jac  · 技术社区  · 16 年前

    所有ID均已设置且正确无误 但是当我试图保存(插入)我得到的订单时 INSERT语句与外键约束“FK_OrderItemDetail_Order”冲突。冲突发生在数据库“MyData”、表“dbo.Order”、列“OrderId”中。

    create a transaction
    transaction.Begin()
    Insert order
    Insert order.LineItems <-- error occurs here
    transaction.Commit
    

    实际代码:

    ...
    entity.Validate();
    if (entity.IsValid)
    {
        SetChangedProperties(entity);
        entity.Install.NagsInstallHours = entity.TotalNagsHours;
        foreach (OrderItemDetail orderItemDetail in entity.OrderItemDetailCollection)
        {
            SetChangedOrderItemDetailProperties(orderItemDetail);
        }
        ValidateRequiredProperties(entity);
        TransactionManager transactionManager = DataRepository.Provider.CreateTransaction();
        EntityState originalEntityState = entity.EntityState;
        try
        {
            entity.OrderVehicle.OrderId = entity.OrderId;
            entity.Install.OrderId = entity.OrderId;
            transactionManager.BeginTransaction();
    
            SaveInsuranceInformation(transactionManager, entity);
            DataRepository.OrderProvider.Save(transactionManager, entity);
            DataRepository.OrderItemDetailProvider.Save(transactionManager, entity.OrderItemDetailCollection);             if (!entity.OrderVehicle.IsEmpty)
            {
                DataRepository.OrderVehicleProvider.Save(transactionManager, entity.OrderVehicle);
            }
            transactionManager.Commit();
        }
        catch
        {
            if (transactionManager.IsOpen)
            {
                transactionManager.Rollback();
            }
            entity.EntityState = originalEntityState;
        }
    }
    ...
    

    有人建议我需要使用两个事务,一个用于订单,一个用于行项目,但我有理由相信这是错误的。但我已经为此奋斗了一天多,我需要解决它,这样我就可以继续前进,即使这意味着使用一个糟糕的工作环境。我可能只是做了些傻事?

    6 回复  |  直到 16 年前
        1
  •  1
  •   qyb2zm302    16 年前

    如果没有看到您的代码,很难说问题出在哪里。它可以是任何数量的东西,但看看这些:

    1. 约束可能在数据库中设置错误。

    您肯定不想使用两个事务。

        2
  •  1
  •   Chris    16 年前

    我自己也使用过NetTiers,发现如果从表中删除外键约束,将其添加回同一个表,然后在数据库中进行更改后再次运行NetTiers的构建脚本,可能有助于重置数据访问层。我偶尔也试过,效果不错。

    祝你好运。

        3
  •  0
  •   Thorsten    16 年前

    看起来您对行项目的insert语句没有正确设置订单的值。。这应该是 Insert order

    我认为你的问题与交易控制无关。

        4
  •  0
  •   Roberto Aloi    16 年前

    我没有这方面的经验,但看起来您可能指定了一个在父表中不可用的键值。对不起,我帮不了你更多的忙。

        5
  •  0
  •   Joel Coehoorn    16 年前

    问题在于如何处理错误。发生错误时,事务不会自动回滚。你当然可以(也可能应该)选择这样做,但取决于你的应用程序或你在哪里,你可能仍然想要提交它。在这种情况下,这正是你正在做的。您需要在那里包装一些错误处理代码,以便在错误发生时回滚代码。

        6
  •  0
  •   Charles Bretana    16 年前

    该错误看起来好像没有为行项目提供正确的 FK医嘱ID 这是在将订单插入订单表时自动生成的。您说您已经检查了ID,您是否也检查了订单详细信息中的FKs?