我尝试用一些小代码解释我的情况:
Class A
{
private IDBTransaction trans;
private IDBConnection conn;
void Main()
{
B test = new B(trans)
[some instruction]
trans = conn.BeginTrans();
test.Save();
}
}
Class B
{
private IDBTransaction trans;
public B(IDBTransaction transaction)
{
trans = transaction;
}
void Save()
{
[some instruction that use transaction]
}
}
当调用Save()时,变量B.trans被设置为null,因为在A传递参数时它是null。然后A.trans更改其值,调用BeginTrans()但B.trans仍然保持为null。我怎么解决?
答案 0 :(得分:1)
您可以将事务保存在单独的对象中,例如
class TransactionInfo
{
public IDbTransaction Transaction;
public IDbConnection conn;
}
然后以这种方式使用它
class A
{
private static TransactionInfo info = new TransactionInfo();
static void Main()
{
B test = new B(info);
//[some instruction]
info.Transaction = info.conn.BeginTransaction();
test.Save();
}
}
class B
{
private TransactionInfo _info;
public B(TransactionInfo info)
{
_info = info;
}
public void Save()
{
//[some instruction that use transaction]
_info.Transaction;
}
}
或您可以延迟您想要获得交易的时刻
public class ValueSource<T>
{
private Func<T> _acessor;
public ValueSource(Func<T> acessor)
{
_acessor = acessor;
}
public T Value
{
get
{
try
{
return _acessor();
}
catch
{
return default(T);
}
}
}
}
然后将上述任何解决方案传递给构造函数。延迟的例子(用于保持在单独的类示例中是相同的)
class A
{
private static IDbTransaction trans;
private static IDbConnection conn;
static void Main()
{
B test = new B(new ValueSource<IDbTransaction>(()=>trans));
//[some instruction]
trans = conn.BeginTransaction();
test.Save();
}
}
class B
{
private ValueSource<IDbTransaction> trans;
public B(ValueSource<IDbTransaction> transactionSource)
{
trans = transactionSource;
}
public void Save()
{
//[some instruction that use transaction]
trans.Value;
}
}
但上述所有示例仅适用于您因某种原因希望将事务引用保留在B类中的情况。如果没有必要,我建议(如问题评论中所建议的那样)将事务作为Save
方法参数传递。
class A
{
private static IDbTransaction Transaction;
private static IDbConnection conn;
static void Main()
{
B test = new B();
//[some instruction]
Transaction = conn.BeginTransaction();
test.Save(Transaction);
}
}
class B
{
public B()
{
}
public void Save(IDbTransaction transaction)
{
//[some instruction that use transaction]
transaction
}
}
请记住:如果没有必要,不要在数据结构中存储任何内容。没有状态的类包含较少的错误,并且更容易测试。
答案 1 :(得分:1)
我会将trans
作为参数传递给Save()
方法而不是构造函数,对于具有更长生命周期的对象持有事务引用是没有用的。 (至少比交易时间长)这样您可以在不同/多个交易中使用Save(trans)
方法。
void Main()
{
B test = new B();
[some instruction]
trans = conn.BeginTrans();
test.Save(trans);
}
Class B
{
void Save(IDBTransaction transaction)
{
}
}