3 回答
TA贡献1772条经验 获得超5个赞
主要有两种交易方式; 连接事务和环境事务。连接事务(例如SqlTransaction)直接绑定到数据库连接(例如SqlConnection),这意味着您必须继续传递连接 - 在某些情况下确定,但不允许“创建/使用/发布”用法,并且不允许跨数据库工作。一个例子(格式化为空格):
using (IDbTransaction tran = conn.BeginTransaction()) { try { // your code tran.Commit(); } catch { tran.Rollback(); throw; }}
不太乱,但仅限于我们的连接“conn”。如果我们想要调用不同的方法,我们现在需要传递“conn”。
另一种选择是环境交易; 在.NET 2.0中,TransactionScope对象(System.Transactions.dll)允许在一系列操作中使用(合适的提供者将自动登记在环境事务中)。这使得可以轻松地改编为现有(非事务性)代码,并与多个提供者交谈(尽管如果您与多个提供者交谈,DTC将参与其中)。
例如:
using(TransactionScope tran = new TransactionScope()) { CallAMethodThatDoesSomeWork(); CallAMethodThatDoesSomeMoreWork(); tran.Complete();}
请注意,这两个方法可以处理它们自己的连接(open / use / close / dispose),但它们将默默地成为环境事务的一部分,而我们不必传递任何内容。
如果您的代码出错,Dispose()将在没有Complete()的情况下被调用,因此它将被回滚。虽然您无法回滚内部事务但完成外部事务,但支持预期的嵌套等:如果任何人不满意,则事务将中止。
TransactionScope的另一个优点是它不仅仅与数据库绑定; 任何支持事务的提供者都可以使用它。例如,WCF。或者甚至有一些与TransactionScope兼容的对象模型(即具有回滚功能的.NET类 - 可能比纪念品更容易,尽管我自己从未使用过这种方法)。
总而言之,这是一个非常非常有用的对象。
一些警告:
在SQL Server 2000上,TransactionScope将立即转到DTC; 这是在SQL Server 2005及更高版本中修复的,它可以使用LTM(更少的开销),直到你与2个源等交谈,当它被提升到DTC时。
有一个小故障意味着您可能需要调整连接字符串
TA贡献1775条经验 获得超8个赞
protected void Button1_Click(object sender, EventArgs e) { using (SqlConnection connection1 = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\Database.mdf;Integrated Security=True;User Instance=True")) { connection1.Open(); // Start a local transaction. SqlTransaction sqlTran = connection1.BeginTransaction(); // Enlist a command in the current transaction. SqlCommand command = connection1.CreateCommand(); command.Transaction = sqlTran; try { // Execute two separate commands. command.CommandText = "insert into [doctor](drname,drspecialization,drday) values ('a','b','c')"; command.ExecuteNonQuery(); command.CommandText = "insert into [doctor](drname,drspecialization,drday) values ('x','y','z')"; command.ExecuteNonQuery(); // Commit the transaction. sqlTran.Commit(); Label3.Text = "Both records were written to database."; } catch (Exception ex) { // Handle the exception if the transaction fails to commit. Label4.Text = ex.Message; try { // Attempt to roll back the transaction. sqlTran.Rollback(); } catch (Exception exRollback) { // Throws an InvalidOperationException if the connection // is closed or the transaction has already been rolled // back on the server. Label5.Text = exRollback.Message; } } } }
- 3 回答
- 0 关注
- 452 浏览
添加回答
举报