具有多线程的共享SQL事务的提示

时间:2012-01-12 10:07:42

标签: c# wcf transactions

我希望不同的调用共享同一个SQL事务。最初的想法是保持一个指向活动事务的静态指针,但这不是线程保存,因为我正在编写WCF服务,所以我应该考虑这些事情。而不是“静态”,我想要的东西是当前上下文的静态。

// The main idea
public override void SaveItem()
{
    using (var transaction = BeginSharedTransaction())
    {
        other1.Save();
        base.SaveItem();
        other2.Save();
        transaction.Commit();
    }
}

// In the base class
public void Save() { ... SaveItem(); ... }
protected virtual void SaveItem() { ... }

// In the base class (or another helper class)
static SqlTransaction _sqlTran = null;
public static SqlTransaction BeginSharedTransaction()
{
    _sqlTran = ... // conn.BeginTransaction();
    return _sqlTran;
}

如果可能,我更倾向于不涉及TransactionScope的解决方案。

编辑 - 我认为我们都同意static SqlTransaction在服务中不好,但这是非线程环境的最初想法。

1 个答案:

答案 0 :(得分:1)

如果通过“共享”意味着对基类和派生类中的SQL操作使用相同的事务对象,则只需在基类中移动事务处理逻辑并为派生提供添加的机会它自己的实现,如下:

// In the base class
protected SqlTransaction Transaction;

public void Save() 
{ 
    ... 
    using (var transaction = BeginSharedTransaction())
    {
        Save(Transaction);

        transaction.Commit();
    }
    ... 
}

public void Save(SqlTransaction transaction) 
{ 
    Transaction = transaction;
    SaveItem();
}

protected virtual void SaveItem() { ... /* uses Transaction on all SQL commands */ ... }

// in the derived class
public override void SaveItem()
{
    other1.Save(Transaction);
    base.SaveItem();
    other2.Save(Transaction);
}


// In the base class (or another helper class)
public static SqlTransaction BeginSharedTransaction()
{
    return ... // conn.BeginTransaction();
}

(根据评论更新的代码)