TransactionScope事务简介

TransactionScope事务简介
在.NET 1.0/1.1 版本我们使⽤SqlTransaction.处理事务
string connString = ConfigurationManager.ConnectionStrings["db"].ConnectionString;
using (var conn = new SqlConnection(connString))
{
conn.Open();
using (IDbTransaction tran = conn.BeginTransaction())
{
try
{
//
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "INSERT INTO Data(Code) VALUES('A-100');";
cmd.Transaction = tran as SqlTransaction;
cmd.ExecuteNonQuery();
}
tran.Commit();
}鸟笼的制作
catch(Exception ex)
{
tran.Rollback();
throw;
}
}
}
到了.NET2.0微软提供了TransactionScope
using (var scope = new TransactionScope())
{
//transctional code…
scope.Complete();
}
TransactionScope使⽤起来简单,只需要把代码写在⼤括号⾥,最后加上scope.Complete();就可以了
接下来主要介绍TransactionScope的简单使⽤
TransactionScope有三个属性:IsolationLevel,Timeout,TransactionScopeOption
Property Default Value Available Options
IsolationLevel(隔离等级)Serializable Serializable, Read Committed, Read Un Committed, Repeatable Read
Timeout(超时)  1 Minute Maximum 10 Minutes
TransactionScopeOption (选项)Required Required, Required
New, Suppress
⽤以下代码可以看到他们属性的值
using (var scope = new System.Transactions.TransactionScope())
{
System.Transactions.IsolationLevel isolationLevel = Transaction.Current.IsolationLevel;
蒸纱机TimeSpan defaultTimeout = TransactionManager.DefaultTimeout;
TimeSpan maximumTimeout = TransactionManager.MaximumTimeout;
}
由图可以看到,TransactionScope默认情况下的隔离等级为Serializable,超时时间为1分钟
Dirty Read(脏读):脏读就是指当⼀个事务正在访问数据,并且对数据进⾏了修改,⽽这种修改还没有提交到数据库中,这时,另外⼀个事务也访问这个数据,然后使⽤了这个数据。
Non Repeatable Read(不可重复读):是指在⼀个事务内,多次读同⼀数据。在这个事务还没有结束时,另外⼀个事务也访问该同⼀数据。那么,在第⼀个事务中的两次读数据之间,由于第⼆个事务的修改,那么第⼀个事务两次读到的的数据可能是不⼀样的。这样就发⽣了在⼀个事务内两次读到的数据是不⼀样的,因此称为是不可重复读。(即不能读到相同的数据内容)
Phantom Read(幻读):是指当事务不是独⽴执⾏时发⽣的⼀种现象,例如第⼀个事务对⼀个表中
的数据进⾏了修改,这种修改涉及到表中的全部数据⾏。同时,第⼆个事务也修改这个表中的数据,这种修改是向表中插⼊⼀⾏新数据。那么,以后就会发⽣操作第⼀个事务的⽤户发现表中还有没有修改的数据⾏,就好象
发⽣了幻觉⼀样。
隔离等级的四种选择:
Serializable(序列化):它在读/写操作时锁定数据。由于这个原因,很多时候它会创建⼀个死锁,因此你可能会得到⼀个超时异常。可以将此隔离级别⽤于⾼度安全的事务性应⽤程序(如⾦融应⽤程序)。缺点是性能低
Repeatable Read(可重复读):同为Serializable,除了允许幻读。可以使⽤在⾦融中的应⽤或严重
事务性应⽤,但需要知道幻读创造的场景是不存在的。
Read Committed(读提交):⼤多数应⽤程序都可以使⽤它。SQLServer默认隔离级别是这个。不会有脏读
Read Un-Committed(读不提交):这些应⽤程序不需要⽀持并发事务。
蜗轮滚刀TransactionScope使⽤:
包装容器
对CommonTest_ExamInfo_ExamStudents表中的⼀个学⽣进⾏修改操作,隔离等级为Read Committed
var option = new TransactionOptions();
option.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
option.Timeout = TimeSpan.FromMinutes(1);
金属表面涂料using (var scope = new TransactionScope(TransactionScopeOption.Required, option))
{
String sql = @"UPDATE Students SET sStuName = @sStuName WHERE sID = @sID AND sIdentityID = @sIdentityID ";
SqlParameter[] args = new SqlParameter[3];
args[0] = new SqlParameter("@sStuName", "张三");
args[1] = new SqlParameter("@sTID", "2017120608575");
args[2] = new SqlParameter("@sIdentityID", "36281763861231231");
if (testDB.Database.ExecuteSqlCommand(sql, args) > 0)
{
scope.Complete();
return true;
}
else
{
return false;
}
}
当执⾏完代码红⾊那⾏后,可以看到,SQLserver启动了隔离等级为Read Committed的事务,然后执⾏修改操作。此时,如果执⾏SELECT TOP 1000  * FROM [dbo].[Students]  SQL语句,如正在修改的数据也包括在内,则不能被查出来,修改操作也是如此。
直到跳出using括号后,查询语句才能被真正执⾏。
但是,此时数据库可以执⾏与事务修改操作⽆关的数据,如执⾏
SELECT * FROM Students
WHERE sTID = '2017120608575'  AND sIdentityID = '36281763861231231'    SQL语句,可以顺利查询到数据
此外,还有⼀点需要说明,当连续执⾏两次相同的修改操作,即第⼆次其实是没有真正修改数据库数据的,此时可以对操作的数据⾏查询
场次安排不使⽤事务和使⽤TransactionScope的Read Committed进⾏对⽐
不使⽤事务如下:
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transacti
{
testDB.Database.ExecuteSqlCommand("delete from dbo.ChildTestList where sTID=@sTid;delete from dbo.ExamStudents where sTID=@sTid;", new                    if (testDB.Database.Connection.State != ConnectionState.Open)
{
testDB.Database.Connection.Open(); //打开Connection连接
}
if(!DbHelper.BulkInsert<ExamStudents>((SqlConnection)testDB.Database.Connection, "ExamStudents", lstExamStudents))
{
if (testDB.Database.Connection.State != ConnectionState.Closed)
{
testDB.Database.Connection.Close(); //关闭Connection连接
}
return false;
}
if (!DbHelper.BulkInsert<ChildTestList>((SqlConnection)testDB.Database.Connection, "ChildTestList", lstCldTestTB))
{
if (testDB.Database.Connection.State != ConnectionState.Closed)
{
testDB.Database.Connection.Close(); //关闭Connection连接
}
return false;
永磁马达
}
if (testDB.Database.Connection.State != ConnectionState.Closed)
{
testDB.Database.Connection.Close(); //关闭Connection连接
}
var testInfo = testDB.TestList.Where(p => p.sTID == sTID).FirstOrDefault();
if (nSaveType == 1)
{
testInfo.nTestState = 14;
}
else
{
testInfo.nTestState = 13;
}
testDB.SaveChanges();
scope.Complete();
return true;
}
添加TransactionScope事务:
以上两图显⽰他们性能上并⽆明显区别。
总结:可以使⽤TransactionScope的Read Committed隔离等级进⾏⼀系列事务操作,性能没有太⼤影响。⼀般不使⽤TransactionScope默认的Serializable隔离等级,因为它需要开很多锁,性能会因此⽽下降。使⽤TransactionScope应注意尽量让using ⼤括号⾥⾯的代码都短⼀些,这样它出错的⼏率更⼩,事务回滚的⼏率也会减少。所以出于数据的⼀致性考虑,⼀系列对数据库的操作可添加TransactionScope的Read Committed隔离等级的事务。

本文发布于:2024-09-21 12:37:53,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/215929.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   事务   修改   操作   没有   需要   隔离   括号
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议