曾几何时,为如何操作事务激动个半天。
曾几何时,还写着这样的事务得意洋洋!
string connStr=@"Data Source=.\sqlexpress;Initial Catalog=DbTest;Integrated Security=True"; using(SqlConnection conn=new SqlConnection(connStr)) { conn.Open(); using (SqlTransaction trans = conn.BeginTransaction()) { SqlCommand cmd = conn.CreateCommand(); cmd.Transaction = trans; try { //操作1 cmd.CommandText = "insert into test1(id) values('aa')"; cmd.ExecuteNonQuery(); //操作2 cmd.CommandText = "insert into test1(id) values('01234567890')";//该句出错,id类型为varchar(10) cmd.ExecuteNonQuery(); trans.Commit(); Console.WriteLine("提交!!"); } catch(Exception e) { Console.WriteLine(e.Message); trans.Rollback(); Console.WriteLine("回滚!!"); } } Console.ReadLine(); }
附上只有一个字段的Test1表:
ID varchar(10) 主键
而后,又发现了Linq to Sql 这个好东西,它是一个轻量级级的ORM,功能非常强大,而且自带事务集成功能。简单的Linq参考资料
我们同样操作上面一个过程,使用Linq如下
1.新建一个 Linq to Sql 类,命名为DataClasses1.dbml,再通过‘服务器资源管理器’ 把数据库中的表添加到设计画面。
2.事务操作如下。
DataClasses1DataContext db = new DataClasses1DataContext(); try { //插入一条ID=1的Test1 的实体。 db.Test1.InsertOnSubmit(new Test1() { ID = "1" }); //插入一条超出限定长度的数据,让它报错 db.Test1.InsertOnSubmit(new Test1() { ID = "01234567890" }); //提交 db.SubmitChanges(); } catch { }
很明显,提交的时候由于存在第二条错误语句,提交失败,第一条语句也被回滚。他的操作时如此简单,而且我们也不必再头疼ORM模型,不必再去写那么原始又容易忘记的事务了。那它是不是完美了呢?
其实不是,我们可以想象一下,如果是一个跨数据库的事务操作呢,显然单单使用Linq是无法解决的。而且,Linq还没成熟,对于不同的数据库,会产生操作的不一致,类似于浏览器的兼容性问题。但Linq真的很强大,不影响其神一般的存在。
最近,对于事务有发现一个 TransactionScope 类,TransactionScope就像一块魔镜,你只要对着他喊:神啊,赐予我事务!你就真的得到了事务。
操作如下:
using (TransactionScope scope = new TransactionScope()) { //操作1,数据库1操作 //操作2,数据库2操作 //操作3 scope.Complete(); }
对于Scope.Complete()之前的任何操作异常,所有操作都会回滚(不管它属于哪个数据库,服务器)。
如此强大的功能,说他为魔镜一点也不为过!