C# 如何在数据上下文中使用事务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/867643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use transactions with a datacontext
提问by user107534
Can I use transactions with a datacontext, so that I can rollback the state of the context after an error? And if so, how does that work?
我可以使用带有数据上下文的事务,以便在出现错误后回滚上下文的状态吗?如果是这样,它是如何工作的?
回答by leppie
I use them in testing all the time :)
我一直在测试中使用它们:)
try
{
dc.Connection.Open();
dc.Transaction = dc.Connection.BeginTransaction();
dc.SubmitChanges();
}
finally
{
dc.Transaction.Rollback();
}
UPDATE
更新
This will ALWAYS rollback after the fact. I use this in testing.
这将始终在事后回滚。我在测试中使用它。
回答by Philippe
Something like this, probably:
大概是这样的:
try
{
using (TransactionScope scope = new TransactionScope())
{
//Do some stuff
//Submit changes, use ConflictMode to specify what to do
context.SubmitChanges(ConflictMode.ContinueOnConflict);
scope.Complete();
}
}
catch (ChangeConflictException cce)
{
//Exception, as the scope was not completed it will rollback
}
回答by Richard
A DataContext will pick up an ambient transaction by default, so it is just a matter of ensuring there is a Transaction in scope. The details become the main issue:
默认情况下,DataContext 将选择环境事务,因此只需确保范围内存在事务即可。细节成为主要问题:
- What options do you need (e.g. isolation level)
- Do you want a new transaction or reuse an existing transaction (e.g. an audit/logging operation might require a new transaction so it can be committed even if the overall business operation fails and thus the outer transaction is rolled back).
- 您需要哪些选项(例如隔离级别)
- 您想要一个新事务还是重用现有事务(例如,审计/日志操作可能需要一个新事务,以便即使整个业务操作失败并因此回滚外部事务也可以提交)。
This is simplified some prototype code, the real code uses helpers to create the transactions with policy driven options (one of the purposes of the prototype was to examine the impact of these options).
这是一些原型代码的简化,真正的代码使用助手创建具有策略驱动选项的事务(原型的目的之一是检查这些选项的影响)。
using (var trans = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions {
IsolationLevel = IsolationLevel.ReadCommitted
},
EnterpriseServicesInteropOption.Automatic)) {
// Perform operations using your DC, including submitting changes
if (allOK) {
trans.Complete();
}
}
If Complete() is not called then the transaction will be rolled back. If there is a containing transaction scope then both the inner and outer transactions need to Complete for the changes on the database to be committed.
如果 Complete() 没有被调用,那么事务将被回滚。如果存在包含事务范围,则内部和外部事务都需要完成才能提交对数据库的更改。
回答by Damien
It's not as simple as the TransactionScope method but, as I understand it, this is the "correct" way to do it for LINQ-to-SQL. It doesn't require any reference to System.Transactions.
它不像 TransactionScope 方法那么简单,但据我所知,这是对 LINQ-to-SQL 执行此操作的“正确”方法。它不需要对 System.Transactions 的任何引用。
dataContext.Connection.Open();
using (dataContext.Transaction = dataContext.Connection.BeginTransaction())
{
dataContext.SubmitChanges();
if (allOK)
{
dataContext.Transaction.Commit();
}
else
{
dataContext.Transaction.RollBack();
}
}
Of course, the RollBack is only required if you intend to do further data operations within the using, otherwise changes will be automatically discarded.
当然,RollBack 仅在您打算在使用中进行进一步的数据操作时才需要,否则更改将被自动丢弃。
回答by Ni?u Alexandru
Is something like this:
是这样的:
using (YourDatacontext m_DB = new YourDatacontext()) using (TransactionScope tran = new TransactionScope()) { try { //make here the changes m_DB.SubmitChanges(); tran.Complete(); } catch (Exception ex) { Transaction.Current.Rollback(); } }
using (YourDatacontext m_DB = new YourDatacontext()) using (TransactionScope tran = new TransactionScope()) { try { //make here the changes m_DB.SubmitChanges(); tran.Complete(); } catch (Exception ex) { Transaction.Current.Rollback(); } }