简体   繁体   中英

Tips for a shared SQL transaction with multi-threading

I want different calls to share the same SQL transaction. The original idea was to keep a static pointer to the active transaction, but this is not thread save, and since I'm writing a WCF service I should consider such things. Instead of "static" I want something that is static to the current context.

// 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;
}

If possible, I would prefer a solution that does not involve TransactionScope .

EDIT - I think we all agree that static SqlTransaction is bad within a service, but that was the original idea for a non-threaded environment.

If by "sharing" you mean using the same transaction object for the SQL operations done in the base class and in the derived class, you could just move the transaction handling logic in the base class and give the derived the chance to add its own implementation, like so:

// 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();
}

(code updated according to comments)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM