问题描述
在 C# .Net 2.0 中进行事务的最佳实践是什么.应该使用哪些类?需要注意的陷阱是什么等等.所有提交和回滚的东西.我刚刚开始一个项目,我可能需要在将数据插入数据库时进行一些事务.欢迎任何关于交易的基本内容的回复或链接.
What are the best practices to do transactions in C# .Net 2.0. What are the classes that should be used? What are the pitfalls to look out for etc. All that commit and rollback stuff. I'm just starting a project where I might need to do some transactions while inserting data into the DB. Any responses or links for even basic stuff about transactions are welcome.
推荐答案
事务主要有 2 种;连接事务和环境事务.连接事务(例如 SqlTransaction)直接绑定到 db 连接(例如 SqlConnection),这意味着您必须不断传递连接 - 在某些情况下可以,但不允许创建/使用/释放"用法,并且不允许跨数据库工作.一个例子(格式化为空格):
There are 2 main kinds of transactions; connection transactions and ambient transactions. A connection transaction (such as SqlTransaction) is tied directly to the db connection (such as SqlConnection), which means that you have to keep passing the connection around - OK in some cases, but doesn't allow "create/use/release" usage, and doesn't allow cross-db work. An example (formatted for space):
using (IDbTransaction tran = conn.BeginTransaction()) {
try {
// your code
tran.Commit();
} catch {
tran.Rollback();
throw;
}
}
不太乱,但仅限于我们的连接conn".如果我们想调用不同的方法,我们现在需要传递conn".
Not too messy, but limited to our connection "conn". If we want to call out to different methods, we now need to pass "conn" around.
替代方案是环境交易;.NET 2.0 中的新增功能,TransactionScope 对象(系统.Transactions.dll) 允许在一系列操作中使用(合适的提供者将自动加入环境事务).这使得改造现有(非事务性)代码和与多个提供者交流变得容易(尽管如果您与多个提供者交流,DTC 会参与进来).
The alternative is an ambient transaction; new in .NET 2.0, the TransactionScope object (System.Transactions.dll) allows use over a range of operations (suitable providers will automatically enlist in the ambient transaction). This makes it easy to retro-fit into existing (non-transactional) code, and to talk to multiple providers (although DTC will get involved if you talk to more than one).
例如:
using(TransactionScope tran = new TransactionScope()) {
CallAMethodThatDoesSomeWork();
CallAMethodThatDoesSomeMoreWork();
tran.Complete();
}
请注意,这两个方法可以处理自己的连接(open/use/close/dispose),但它们将默默地成为环境事务的一部分,而无需我们传入任何内容.
Note here that the two methods can handle their own connections (open/use/close/dispose), yet they will silently become part of the ambient transaction without us having to pass anything in.
如果你的代码出错,Dispose() 将在没有 Complete() 的情况下被调用,因此它会被回滚.支持预期的嵌套等,尽管您不能回滚内部事务并完成外部事务:如果有人不满意,事务将被中止.
If your code errors, Dispose() will be called without Complete(), so it will be rolled back. The expected nesting etc is supported, although you can't roll-back an inner transaction yet complete the outer transaction: if anybody is unhappy, the transaction is aborted.
TransactionScope 的另一个优点是它不仅仅与数据库绑定;任何事务感知提供者都可以使用它.例如,WCF.或者甚至还有一些与 TransactionScope 兼容的对象模型(即具有回滚功能的 .NET 类 - 也许比纪念品更容易,尽管我自己从未使用过这种方法).
The other advantage of TransactionScope is that it isn't tied just to databases; any transaction-aware provider can use it. WCF, for example. Or there are even some TransactionScope-compatible object models around (i.e. .NET classes with rollback capability - perhaps easier than a memento, although I've never used this approach myself).
总而言之,一个非常非常有用的对象.
All in all, a very, very useful object.
一些注意事项:
- 在 SQL Server 2000 上,TransactionScope 将立即转到 DTC;这在 SQL Server 2005 及更高版本中已修复,当它提升为 DTC 时,它可以使用 LTM(开销更少),直到您与 2 个源等交谈.
- 有一个故障,这意味着您可能需要进行调整您的连接字符串
- On SQL Server 2000, a TransactionScope will go to DTC immediately; this is fixed in SQL Server 2005 and above, it can use the LTM (much less overhead) until you talk to 2 sources etc, when it is elevated to DTC.
- There is a glitch that means you might need to tweak your connection string
这篇关于.net 中的交易的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!