TransactionScope 内的父子插入导致外键约束错误

Posted

技术标签:

【中文标题】TransactionScope 内的父子插入导致外键约束错误【英文标题】:Parent-Child Insertion inside TransactionScope cause foreign key constraint error 【发布时间】:2015-06-26 16:18:46 【问题描述】:

我正在尝试在TransactionScope 中插入父子关系的数据,但出现INSERT statement conflicted with the FOREIGN KEY constraint 错误。这是我的代码:

using (var scope = new TransactionScope())

    try
    
        discount = discountDataAccess.Insert(discount);
        switch (discount.Type)
        
            case eDiscountType.PerCustomer:
                InsertDiscountCustomer(discount.Id, idList);
                break;

            case eDiscountType.PerPackage:
                InsertDiscountPackage(discount.Id, idList);
                break;
        

        scope.Complete();
        return discount;
    
    catch (Exception ex)
    
        scope.Dispose();
        throw;
    
 

DiscountCustomerDiscountPackage 将被插入时,Discount.Id 仍然是0,因为在调用scope.Complete() 之前没有数据插入到数据库中。所以基本上我无法保存DiscountCustomerDiscountPackage,直到我提交DiscountTransaction 在两者都成功保存之前不会提交。

有没有办法在TransactionScope 中同时插入父子元素?

【问题讨论】:

【参考方案1】:

我发现分布式事务是不可能的,因为TransactionScope 仍然在方法的上下文中,并且在调用scope.Complete() 之前不会插入任何内容,但是可以通过SqlTransaction 类来完成,该类可以从中检索SqlConnection.

try

    var transaction = connection.BeginTransaction();
    discount = discountDataAccess.Insert(discount, transaction);
    switch (discount.Type)
    
        case eDiscountType.PerCustomer:
            InsertDiscountCustomer(discount.Id, idList, transaction);
            break;

        case eDiscountType.PerPackage:
            InsertDiscountPackage(discount.Id, idList, transaction);
            break;
    

    transaction.Commit();
    return discount;

catch (Exception ex)

    if (transaction != null)
        transaction.Rollback();

    throw;

【讨论】:

以上是关于TransactionScope 内的父子插入导致外键约束错误的主要内容,如果未能解决你的问题,请参考以下文章

探索逻辑事务 TransactionScope

分布式事务TransactionScope所导致几个坑

C#分布式事务解决方案-TransactionScope

为啥 TransactionScope 不能与 Sqlite 一起使用?

TransactionScope事务操作

TransactionScope 如何回滚事务?