.net中的4种事务总结 .
在一个MIS系统中,没有用事务那就绝对是有问题的,要么就只有一种情况:你的系统实在是太小了,业务业务逻辑有只要一步执行就可以完成了。因此掌握事务处理的方法是很重要,进我的归类在.net中大致有以下4种事务处理的方法。大家可以参考一下,根据实际选择适当的事务处理。
1 SQL事务
sql事务是使用SQL server自身的事务:在存储过程中直接使用Begin Tran,Rollback Tran,Commit Tran实现事务:
优点:执行效率最佳
限制:事务上下文仅在数据库中调用,难以实现复杂的业务逻辑。
Demo:(所有demo,都以SQL Server自带的Northwind数据的表Region为例)
View Code
CREATE PROCEDURE dbo.SPTransaction ( @UpdateID int, @UpdateValue nchar(50), @InsertID int, @InsertValue nchar(50) ) AS begin Tran Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID insert into Region Values (@InsertID,@InsertValue) declare @RegionError int select @RegionError=@@error if(@RegionError=0) COMMIT Tran else ROLLBACK Tran GO /// <summary> /// SQL事务: /// </summary> public void SQLTran() { SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;"); SqlCommand cmd = new SqlCommand(); cmd.CommandText = "SPTransaction"; cmd.CommandType = CommandType.StoredProcedure; cmd.Connection = conn; conn.Open(); SqlParameter[] paras= new SqlParameter[]{ new SqlParameter ("@UpdateID",SqlDbType.Int,32), new SqlParameter ("@UpdateValue",SqlDbType .NChar,50), new SqlParameter ("@InsertID",SqlDbType.Int ,32), new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)}; paras[0].Value = "2"; paras[1].Value = "Update Value1"; paras[2].Value = "6"; paras[3].Value = "Insert Value1"; foreach (SqlParameter para in paras ) { cmd.Parameters.Add(para); } cmd.ExecuteNonQuery(); }
2 ADO.net事务
Ado.net事务可能是大家一般都用的
优点:简单,效率和数据库事务差不多。
缺点:事务不能跨数据库,只能在一个数据库连接上。如果是两个数据库上就不能使用该事务了。
Demo:
View Code
/// <summary> /// 一般的ADO.net 事务 /// </summary> public void ADONetTran1() { SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;"); SqlCommand cmd = new SqlCommand(); try { cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID"; cmd.CommandType = CommandType.Text; cmd.Connection = conn; conn.Open(); SqlParameter[] paras = new SqlParameter[]{ new SqlParameter ("@UpdateID",SqlDbType.Int,32), new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)}; paras[0].Value = "2"; paras[1].Value = "Update Value12"; foreach (SqlParameter para in paras) { cmd.Parameters.Add(para); } //开始事务 cmd.Transaction = conn.BeginTransaction(); cmd.ExecuteNonQuery(); cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)"; cmd.CommandType = CommandType.Text; paras = new SqlParameter[]{ new SqlParameter ("@InsertID",SqlDbType.Int ,32), new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)}; paras[0].Value = "7"; paras[1].Value = "Insert Value"; cmd.Parameters.Clear(); foreach (SqlParameter para in paras) { cmd.Parameters.Add(para); } cmd.ExecuteNonQuery(); //提交事务 cmd.Transaction.Commit(); } catch { //回滚事务 cmd.Transaction.Rollback(); throw; } finally { conn.Close(); } }
3 TransactionScope事务
TransactionScope事务类,它可以使代码块成为事务性代码。并自动提升为分布式事务
优点:实现简单,同时能够自动提升为分布式事务
Demo:
View Code
/// <summary> /// TransactionScope事务:可自动提升事务为完全分布式事务的轻型(本地)事务。 /// 使用时要保证MSDTC服务(控制分布事务)是开启的可以使用:net start msdtc命令开启服务; /// </summary> public void ADONetTran2() { SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;"); SqlCommand cmd = new SqlCommand(); try { using (System.Transactions.TransactionScope ts = new TransactionScope()) { cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID"; cmd.CommandType = CommandType.Text; cmd.Connection = conn; conn.Open(); SqlParameter[] paras = new SqlParameter[]{ new SqlParameter ("@UpdateID",SqlDbType.Int,32), new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)}; paras[0].Value = "2"; paras[1].Value = "Update Value12"; foreach (SqlParameter para in paras) { cmd.Parameters.Add(para); } cmd.ExecuteNonQuery(); cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)"; cmd.CommandType = CommandType.Text; paras = new SqlParameter[]{ new SqlParameter ("@InsertID",SqlDbType.Int ,32), new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)}; paras[0].Value = "8"; paras[1].Value = "Insert Value"; cmd.Parameters.Clear(); foreach (SqlParameter para in paras) { cmd.Parameters.Add(para); } cmd.ExecuteNonQuery(); //提交事务 ts.Complete(); } } catch { throw; } finally { conn.Close(); } }
4 COM+事务
在分布式应用程序中,往往要同时操作多个数据库,使用数据库事务就不能满足业务的要求了。在COM+中,提供完整的事务处理服务。很方便处理多个数据库上的事务。
Demo:
View Code
/// <summary> /// COM+事务 /// </summary> public void ComTran() { SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;"); SqlCommand cmd = new SqlCommand(); ServiceConfig sc = new ServiceConfig(); //指定事务类型 sc.Transaction = TransactionOption.Required; //设置启动跟踪 sc.TrackingEnabled = true; //创建一个上下文,该上下文的配置由作为 cfg 参数传递的 ServiceConfig 对象来指定。 //随后,客户端和服务器端的策略均被触发,如同发生了一个方法调用。 //接着,新的上下文被推至上下文堆栈,成为当前上下文 ServiceDomain.Enter(sc); try { cmd.CommandText = "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID"; cmd.CommandType = CommandType.Text; cmd.Connection = conn; conn.Open(); SqlParameter[] paras = new SqlParameter[]{ new SqlParameter ("@UpdateID",SqlDbType.Int,32), new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)}; paras[0].Value = "2"; paras[1].Value = "Update Value22"; foreach (SqlParameter para in paras) { cmd.Parameters.Add(para); } cmd.ExecuteNonQuery(); cmd.CommandText = "insert into Region values(@InsertID,@InsertValue)"; cmd.CommandType = CommandType.Text; paras = new SqlParameter[]{ new SqlParameter ("@InsertID",SqlDbType.Int ,32), new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)}; paras[0].Value = "9"; paras[1].Value = "Insert Value"; cmd.Parameters.Clear(); foreach (SqlParameter para in paras) { cmd.Parameters.Add(para); } cmd.ExecuteNonQuery(); //提交事务 ContextUtil.SetComplete(); } catch { //回滚事务 ContextUtil.SetAbort(); throw; } finally { conn.Close(); //触发服务器端的策略,随后触发客户端的策略,如同一个方法调用正在返回。 //然后,当前上下文被弹出上下文堆栈,调用 Enter 时正在运行的上下文成为当前的上下文。 ServiceDomain.Leave(); } }