TransactionScope事务简介

TransactionScope事务简介在.NET1.0/1.1版本我们使用SqlTransaction.处理事务stringconnString=ConfigurationManager.ConnectionStrings["db"].ConnectionString;using(varconn=newSqlConnection(connString)){conn.Open();usi…

大家好,又见面了,我是你们的朋友全栈君。

.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
        {
            // transactional code...
            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事务简介

由图可以看到,TransactionScope默认情况下的隔离等级为Serializable,超时时间为1分钟

 

Dirty Read(脏读):脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

Non Repeatable Read(不可重复读):是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即不能读到相同的数据内容)

Phantom Read(幻读):是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象

发生了幻觉一样。

TransactionScope事务简介

隔离等级的四种选择:

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;
                    }
}

TransactionScope事务简介

当执行完代码红色那行后,可以看到,SQLserver启动了隔离等级为Read Committed的事务,然后执行修改操作。 此时,如果执行

SELECT TOP 1000  * FROM [dbo].[Students]  SQL语句,如正在修改的数据也包括在内,则不能被查出来,修改操作也是如此。

TransactionScope事务简介

直到跳出using括号后,查询语句才能被真正执行。

但是,此时数据库可以执行与事务修改操作无关的数据,如执行

SELECT * FROM Students

WHERE sTID = ‘2017120608575’  AND sIdentityID = ‘36281763861231231’    SQL语句,可以顺利查询到数据

TransactionScope事务简介

此外,还有一点需要说明,当连续执行两次相同的修改操作,即第二次其实是没有真正修改数据库数据的,此时可以对操作的数据行查询

TransactionScope事务简介

场次安排不使用事务和使用TransactionScope的Read Committed进行对比

 

不使用事务如下:

TransactionScope事务简介

TransactionScope事务简介TransactionScope事务简介

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }))
{
                    testDB.Database.ExecuteSqlCommand("delete from dbo.ChildTestList where sTID=@sTid;delete from dbo.ExamStudents where sTID=@sTid;", new SqlParameter("@sTid", sTID));
                    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事务简介

TransactionScope事务简介TransactionScope事务简介

以上两图显示他们性能上并无明显区别。

 

总结:可以使用TransactionScopeRead Committed隔离等级进行一系列事务操作,性能没有太大影响。一般不使用TransactionScope默认的Serializable隔离等级,因为它需要开很多锁,性能会因此而下降。使用TransactionScope应注意尽量让using大括号里面的代码都短一些,这样它出错的几率更小,事务回滚的几率也会减少。所以出于数据的一致性考虑,一系列对数据库的操作可添加TransactionScopeRead Committed隔离等级的事务。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/161923.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ubuntu系统查看gcc版本及版本切换[通俗易懂]

    ubuntu系统查看gcc版本及版本切换[通俗易懂]写在前面:自己的测试环境是Ubuntu16.04,安装了gcc-5、gcc-7,通过下面的方式从实现默认的gcc-5切换到gcc-7,亲测有效~~1.查看自己当前的gcc版本gcc-v通过下图的最后一行可以得到,这里电脑当前gcc的版本是5.42.安装另一个版本gcc我这里安装的是gcc-7sudoadd-apt-repositoryppa:ubuntu-toolch…

    2022年6月26日
    156
  • 加多宝为什么会输给王老吉_加多宝王老吉占比

    加多宝为什么会输给王老吉_加多宝王老吉占比如果评选世界营销战最激烈案例,2012年爆发的王老吉与加多宝之间的品牌大战一定榜上有名。那是一场由一个小小红罐引发的“血战”。一、缘起加、王之争的来龙动脉我就不细说了,大概起因是若干年前国企广药将其旗下的传统凉茶品牌“王老吉”部分(红罐)租给了与王老吉凉茶创始者后人有关的香港鸿道集团旗下的加多宝集团。这种做法本来十分普遍没啥特别,但没想到的是加多宝的市场运作能力超强,竟然在短短几年内将一种原来…

    2025年7月15日
    0
  • 开源自动化运维平台Spug

    开源自动化运维平台Spug开源自动化运维平台SpugSpug演示环境特性安装Docker安装安装步骤1.安装docker2.拉取镜像3.启动容器4.初始化5.访问测试6.版本升级SpugSpug是面向中小型企业设计的轻量级无Agent的自动化运维平台,整合了主机管理、主机批量执行、主机在线终端、应用发布部署、在线任务计划、配置中心、监控、报警等一系列功能。官网地址:https://spug.cc使用文档:https://spug.cc/docs/about-spug/更新日志:https://spug.cc

    2022年5月17日
    56
  • BIOS和EC

    BIOS和EC08年做MID时候的一个PPT.Agenda硬件平台BIOS介绍功能类型,种类内部模块(AWARD为例)EC介绍功能(IT8511ELPCEC为例)EC与BIOS关系硬件平台BIOS介绍BIOS(BasicInputOutputSystem)即基本输入/输出系统。存放在一个不需要电源的记忆体(芯片)中,这就

    2022年7月20日
    41
  • svn客户端的安装与使用教程(svn汉化教程)

    SVN服务端与客户端安装使用(客户端汉化包)客户端下载地址:https://tortoisesvn.net/downloads.zh.html下载64位SVN安装包和64位简体中文安装包安装SVN打开安装包,直接NextNext选择安装目录,如果是自定义目录要新建一个文件夹,否则会把安装文件散落在盘符(此处不安装命令行工具会导致在idea中无法使用subversio…

    2022年4月17日
    55
  • java中stringBuilder常用方法[通俗易懂]

    java中stringBuilder常用方法[通俗易懂]String对象是不可改变的。每次使用System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的String对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用System.Text.StringBuilder类。例如,当在一个循环中将许多字符串连接在一起时,使用StringBuilder类可以提升性能。通过用一个重载的构造函数方法初始化变量,可以创建StringBuild

    2022年7月17日
    25

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号