【问题标题】:Tips for a shared SQL transaction with multi-threading多线程共享 SQL 事务的提示
【发布时间】:2012-01-12 10:07:41
【问题描述】:

我希望不同的调用共享同一个 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 在服务中不好,但这是非线程环境的最初想法。

【问题讨论】:

  • 您是否可以与我们分享一个实际有用的场景?
  • 在我的示例中,事务在调用者“other1”和“other2”之间共享。
  • 您提到了 WCF,但没有说明您正在使用的 InstanceContextMode,或者您是否/如何使用 WCF 的 TransasctionScopeOption 属性。 WCF 应该能够为您做很多这样的工作。
  • 特伦斯,我不知道,我在哪里可以找到那些东西?
  • Terence,如果您能给我一些建议或链接,我将不胜感激。

标签: c# wcf transactions


【解决方案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();
}

(根据cmets更新代码)

【讨论】:

  • 但是 other1.Save() 和 other2.Save() 都将尝试开始并提交事务。
  • 你是对的;我错过了。我会找到解决方案并更新代码
  • 我已经更新了代码 - 我建议使用 void Save(SqlTransaction transaction) 重载,它允许将现有事务注入给定的 ClassWithUnknownNameThatDoesSomeSqlStuff 实例
  • 这应该可以工作,前提是当前实例以及其他 1 和 other2 没有在多个请求之间共享(我想在请求之间共享这些没有多大意义)
  • 应该可以。只是出于好奇/最佳实践,您认为即使不需要它(例如单个呼叫)也为每个呼叫启动事务是一个好主意吗?在我原来的帖子中,我试图做一些交易只会在需要时发生的事情。
猜你喜欢
  • 1970-01-01
  • 2021-09-12
  • 2011-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-18
相关资源
最近更新 更多