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

LINQ to SQL中的事务

  •  2
  • hIpPy  · 技术社区  · 17 年前

    mainTransaction (tScope)
         Operation 1 changes
         db.submitChanges()
    
         Operation 2 changes
         db.submitChanges()    
         ...
    
         catch(TransactionException ex)
             'rollback mainTransaction
    
         tScope.complete()
    

    应该能够看到 从操作1开始的更改,如果任何操作失败,则所有先前的操作都将回滚。

    我可以想到Linq-to-Sql中的嵌套事务,但也许有更好的方法。我还没有尝试嵌套事务方法。

    mainTransaction
        childTransaction #1 
            child 1 changes
    
        childTransaction #2 changes
            should see child 1 changes
            child 2 changes
    
        childTransaction #3 changes
            should see child 1 changes
            should see child 2 changes
            child #3 changes
    
    catch(TransactionException ex)
        'rollback child 1
        'rollback child 2
        ...
    tScope.complete()
    

    更新:假设我们有一个父母和一个孩子的关系。父级将引用子集合作为父级。Childs实体集。在所有操作中,我传递父引用并将子EntitySet作为父引用。孩子们。我在Childs-Linq表中添加子记录,而不是Childs-EntitySet。在操作#1之后,我执行db.submitChanges()。对于操作#2,我在父级中没有看到操作#1的插入记录。Childs EntitySet甚至在db之后。SubmitChanges()-但是,我在Child-Linq表中看到了。有什么想法吗?

    我想用Linq来反对。Linq to Object在后续操作中似乎没有“看到”InsertOnSubmit记录(例如:如果我在子表中插入一条记录,则从父关系返回的EntitySet不会显示插入的记录)。

    2 回复  |  直到 17 年前
        1
  •  0
  •   Maslow    17 年前

    如果每个父表的数据大小都足够可管理,我使用了一个列表(linqToSqlRowType)来跟踪填充和添加的新行。因此,我查询了列表中尚未提交更改的子操作。

    此外,在Linq-to-sql(可能也是Linq-to-objects)中,您可以将外键行字段设置为尚未提交的行,它将自动处理任何标识字段。

        2
  •  0
  •   hIpPy    13 年前

    虽然很晚了,但我想回答这个问题。

    选项1 :与 TransactionScope 我不喜欢这个。

    // if an exception is thrown, ts.Complete() is not called causing rollback
    using (TransactionScope ts = new TransactionScope())
    {
        // operation 1 changes //
        var items = db.Items.ToList();
        var itemToFind = items.Where(somePredicate);
        db.Items.InsertOnSubmit(item1);
        db.Items.InsertOnSubmit(item2);
        db.SubmitChanges();
    
        // operation 2 changes //
        // re-query the table(s) again
        var items = db.Items.ToList();
        var itemToFind = items.Where(somePredicate);
        db.Items.InsertOnSubmit(item3);
        db.SubmitChanges()
    
        ts.Complete();
    }
    

    选项2 context.GetChangeSet() s Inserts , Updates 或 Deletes .

    // operation 1 changes //
    var items = db.Items.ToList();
    var itemToFind = items.Where(somePredicate);
    db.Items.InsertOnSubmit(item1);
    db.Items.InsertOnSubmit(item2);
    // do not submit changes here
    
    // operation 2 changes //
    // look in the ChangeSet
    var itemToFind = items.Where(somePredicate);
    if (itemToFind = null)
        itemToFind = db.GetChangeSet().Inserts.OfType<Item>().Where(somePredicate);
    db.Items.InsertOnSubmit(item3);
    db.SubmitChanges()    
    
    // submit changes when all done
    db.SubmitChanges();
    

    选项3 :保留一个单独的列表并查看(类似于选项2)。

    // operation 1 changes //
    var items = db.Items.ToList();
    var itemToFind = items.Where(somePredicate);
    db.Items.InsertOnSubmit(item1);
    db.Items.InsertOnSubmit(item2);
    customList.Add(item1);
    customList.Add(item2);
    // do not submit changes here
    
    // operation 2 changes //
    // look in the ChangeSet
    var itemToFind = items.Where(somePredicate);
    if (itemToFind = null)
        itemToFind = customList.Where(somePredicate);
    db.Items.InsertOnSubmit(item3);
    db.SubmitChanges()    
    
    // submit changes when all done
    db.SubmitChanges();