TransactionScope使用说明

TransactionScope使用说明参考MSDN:http://msdn.microsoft.com/zh-cn/library/system.transactions.transactionscope.aspx转载自:http://www.cnblogs.com/blsong/archive/2010/08/13/1798987.html感谢原作者。TransactionScope是.NetFramework

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

参考MSDN :http://msdn.microsoft.com/zh-cn/library/system.transactions.transactionscope.aspx

转载自:http://www.cnblogs.com/blsong/archive/2010/08/13/1798987.html 感谢原作者。

TransactionScope是.Net Framework 2.0滞后,新增了一个名称空间。它的用途是为数据库访问提供了一个“轻量级”[区别于:SqlTransaction]的事物。使用之前必须添加对 System.Transactions.dll 的引用。

       下列代码就是一个正在创建的事务,这个事务自身还封装了多个数据库查询。只要任意一个 SqlCommand 对象引发异常,程序流控制就会跳出 TransactionScope 的 using 语句块,随后,TransactionScope 将自行释放并回滚该事务。由于这段代码使用了 using 语句,所以 SqlConnection 对象和 TransactionScope 对象都将被自动调用Dispose()释放。由此可见,只需添加很少的几行代码,您就可以构建出一个事务模型,这个模型可以对异常进行处理,执行结束后会 自行清理,此外,它还可以对命令的提交或回滚进行管理。

 

//创建TransactionScope
using (TransactionScope tsCope= new TransactionScope())
{
	using (SqlConnection cn2005= new SqlConnection(someSql2005))
	{
	SqlCommand cmd= new SqlCommand(sqlUpdate, cn2005);
	cn2005.Open();
	cmd.ExecuteNonQuery();
	}
	using (SqlConnection cn2005= new SqlConnection(anotherSql2005))
	{
	SqlCommand cmd= new SqlCommand(sqlDelete, cn2005);
	cn2005.Open();
	cmd.ExecuteNonQuery();
	}
 tsCope.Complete();
} 

连接字符串关键字(Enlist)

       SqlConnection.ConnectionString 属性支持关键字 Enlist,该关键字指示 System.Data.SqlClient 是否将检测事务上下文并自动在分布式事务中登记连接。 如果 Enlist=true,连接将自动在打开的线程的当前事务上下文中登记。 如果 Enlist=false,SqlClient 连接不会与分布式事务进行交互。 Enlist 的默认值为 true。 如果连接字符串中未指定 Enlist,若在连接打开时检测到一个,连接将自动在分布式事务中登记。  

Server=(local)SQL2005;Database=Northwind;Integrated Security=SSPI;auto-enlist=false

        上面所看到的示例中我们使用了TransactionScope的默认设置。TransactionScope有三种模式:

TransactionScopeOptions

描述

Required

如果已经存在一个事务,那么这个事务范围将加入已有的事务。否则,它将创建自己的事务。

RequiresNew

这个事务范围将创建自己的事务。

Suppress

如果处于当前活动事务范围内,那么这个事务范围既不会加入氛围事务 (ambient transaction),也不会创建自己的事务。当部分代码需要留在事务外部时,可以使用该选项。

       您可以在代码的任何位置上随是查看是否存在事务范围,具体方法就是查看 System.Transactions.Transaction.Current 属性。如果这个属性为“null”,说明不存在当前事务。
       若要更改 TransactionScope 类的默认设置,您可以创建一个 TransactionOptions 对象,然后通过它在 TransactionScope 对象上设置隔离级别和事务的超时时间。TransactionOptions 类有一个 IsolationLevel 属性,通过这个属性可以更改隔离级别,例如从默认的可序列化 (Serializable) 改为ReadCommitted,甚至可以改为 SQL Server 2005 引入的新的快照 (Snapshot) 级别。(请记住,隔离级别仅仅是一个建议。大多数数据库引擎会试着使用建议的隔离级别,但也可能选择其他级别。)此 外,TransactionOptions 类还有一个 TimeOut 属性,这个属性可以用来更改超时时间(默认设置为 1 分钟)。
       下列代码中使用了默认的 TransactionScope 对象及其默认构造函数。也就是说,它的隔离级别设置为可序列化 (Serializable),事务的超时时间为 1 分钟,而且 TransactionScopeOptions 的设置为 Required。

TransactionOptions tOpt= new TransactionOptions();
//设置TransactionOptions模式
tOpt.IsolationLevel= IsolationLevel.ReadCommitted;
// 设置超时间隔为2分钟,默认为60秒
tOpt.Timeout= new TimeSpan(0,2,0);
string cnString= ConfigurationManager.ConnectionStrings["sql2005DBServer"].ConnectionString);
using (TransactionScope tsCope= new TransactionScope(TransactionScopeOption.RequiresNew, tOpt))
{
using (SqlConnection cn2005= new SqlConnection(cnString)
{
SqlCommand cmd= new SqlCommand(updateSql1, cn2005);
cn2005.Open();
cmd.ExecuteNonQuery();
}
tsCope.Complete();
} 

嵌套应用

 如下列代码,假设 Method1 创建一个 TransactionScope,针对一个数据库执行一条命令,然后调用 Method2。Method2 创建一个自身的 TransactionScope,并针对一个数据库执行另一条命令。      

private void Method1()
{
using (TransactionScope ts=
new TransactionScope(TransactionScopeOption.Required))
{
using (SqlConnection cn2005= new SqlConnection())
{
SqlCommand cmd= new SqlCommand(updateSql1, cn2005);
cn2005.Open();
cmd.ExecuteNonQuery();
}
Method2();
ts.Complete();
}
}
private void Method2()
{
using (TransactionScope ts=
new TransactionScope(TransactionScopeOption.RequiresNew))
{
using (SqlConnection cn2005= new SqlConnection())
{
SqlCommand cmd= new SqlCommand(updateSql2, cn2005);
cn2005.Open();
cmd.ExecuteNonQuery();
}
ts.Complete();
}
} 

       总结:
       进入和退出事务都要快,这一点非常重要,因为事务会锁定宝贵的资源。最佳实践要求我们在需要使用事务之前再去创建它,在需要对其执行命令前迅速打开连接, 执行动作查询 (Action Query),并尽可能快地完成和释放事务。在事务执行期间,您还应该避免执行任何不必要的、与数据库无关的代码,这能够防止资源被毫无疑义地锁定过长的 时间。

其他使用方法:

NisShinContext context = new NisShinContext();
            try
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    NisshinMenuFather sysDept = context.NisshinMenuFathers.FirstOrDefault(dept => dept.MenuFatherID == 3);
                    sysDept.MenuFatherName = "临沂****公司";
                    context.SaveChanges();
                    //新增一记录
                    sysDept = new NisshinMenuFather
                    {
                        MenuFatherID = 4,
                        MenuFatherName = "菏泽***公司",
                        CreatePeople = "admin",
                        CreateDateTime = DateTime.Now
                    };
                    context.NisshinMenuFathers.Add(sysDept);
                    //保存到数据库
                    int i = context.SaveChanges();
                    //提交事务
                    ts.Complete();
                    Console.WriteLine("已成功执行,影响行数:" + i);
                }
               
            }
            catch (Exception ex)
            {
                Console.WriteLine("发生异常,已回滚" + ex.Message);
            }

经过测试验证,在transaction.Complete()之前的代码中只要出现异常,事务就会回滚。

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

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

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


相关推荐

  • python+opencv图像模板匹配—多模板匹配

    python+opencv图像模板匹配—多模板匹配

    2021年10月6日
    37
  • 嵌入式Linux移植USB网卡驱动「建议收藏」

    嵌入式Linux移植USB网卡驱动「建议收藏」硬件平台:realARM6410操作系统:fedorakernel2.6.33.3-85.fc13.i686.PAE交叉编译器:arm-none-linux-gnueabigccversion4.3.2WIFI模组:磊科NW336芯片realtek8188cus

    2022年9月24日
    0
  • ZBrush中必须记住的常用快捷键

    ZBrush中必须记住的常用快捷键ZBrush是一款数字雕刻和绘画软件,它以强大的功能和直观的工作流程彻底改变了整个三维雕刻行业。强大的功能离不开便捷的操作,为此ZBrush提供了一系列常用操作快捷键,熟练掌握这些快捷键

    2022年8月2日
    3
  • java面试题csdn_java底层面试题

    java面试题csdn_java底层面试题问题是:n只奶牛坐在一排,每个奶牛拥有ai个苹果,现在你要在它们之间转移苹果,使得最后所有奶牛拥有的苹果数都相同,每一次,你只能从一只奶牛身上拿走恰好两个苹果到另一个奶牛上,问最少需要移动多少次可以平分苹果,如果方案不存在输出-1输出描述:输出一行表示最少需要移动多少次可以平分苹果,如果方案不存在则输出-1。输入例子:471595输出例子:3im…

    2022年8月31日
    1
  • BufferedWriter写int型数据

    BufferedWriter写int型数据在做项目的过程中遇到用BufferedWriter.writer(…)写文件的,但是在写入int型数据时是乱码。在翻阅了API后发现,BufferedWriter.writer(intc)方法写的不是一个int型数据,而是一个character型数据:因此,在用BufferedWriter.writer写数据的时候,如果要写int型数据,可以先把它转成String型的数据,这样就

    2022年6月10日
    44
  • java基础编程入门教程,2022最新

    java基础编程入门教程,2022最新Java学习到什么程度可以找第一份工作自己买了本Java从入门到精通。以为可以很快地学完,非CS专业。现在我想说所有系列的从入门到精通都是垃圾,一年多来,我每天白天看视频,晚上敲代码到凌晨,我是一个很倔的人,我认为天下没有任何东西是人类学不会的,所以我就付出高三一样的时间去学习。为你解读Java三大框架其实作为Java初学者除了简单的学习框架本身,还需要思考更多的东西,比如有框架和没有框架到底给你带来了什么?用Struts,要充分的理解MVC思想,用Hibernate,要明白什么是持久化,什么是OR/m

    2022年7月9日
    18

发表回复

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

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