在一个MIS系统中,没有用事务那就绝对是有问题的,要么就只有一种情况:你的系统实在是太小了,业务业务逻辑有只要一步执行就可以完成了。因此掌握事务处理的方法是很重要,进我的归类在.net中大致有以下4种事务处理的方法。大家可以参考一下,根据实际选择适当的事务处理。
1 SQL事务
    sql事务是使用SQL server自身的事务:在存储过程中直接使用Begin Tran,Rollback Tran,Commit Tran实现事务:
优点:执行效率最佳
限制:事务上下文仅在数据库中调用,难以实现复杂的业务逻辑。
Demo:(所有demo,都以SQL Server自带的Northwind数据的表Region为例)


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
执行带事务的存储过程

2 ADO.net事务
   Ado.net事务可能是大家一般都用的
 优点:简单,效率和数据库事务差不多。
 缺点:事务不能跨数据库,只能在一个数据库连接上。如果是两个数据库上就不能使用该事务了。
Demo1:


/// <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();
            }

        }
Demo2:

public static string DBCon = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();

 public bool Transcation(string sql)
{
using (SqlConnection connection = new SqlConnection(BLL_Class.DBCon))
{
connection.Open(); SqlCommand command = connection.CreateCommand();
SqlTransaction transaction; //启动事务
transaction = connection.BeginTransaction("SampleTransaction"); //设定SqlCommand的事务和连接对象
command.Connection = connection;
command.Transaction = transaction; try
{
command.CommandText = sql;
command.ExecuteNonQuery(); // 完成提交
transaction.Commit();
return true; }
catch (Exception ex)
{
//数据回滚
transaction.Rollback(); return false;
}
}
}

  

 
 

3 TransactionScope事务
  TransactionScope事务类,它可以使代码块成为事务性代码。并自动提升为分布式事务
 优点:实现简单,同时能够自动提升为分布式事务
Demo:


 /// <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:


/// <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();
            }

        }

在.net中还有些也能进行事务处理,如web Service中

需要特别补充的是:
如果你使用的是分布事务(TransactionScope事务和COM+事务),在默认情况下你是要重新配置安装SQL Server数据库服务器和访问数据库的客户端的.(如果没有配置运行会出现以下错误:该伙伴事务管理器已经禁止了它对远程/网络事务的支持。 (异常来自 HRESULT:0x8004D025)
)下面是MSDN上关于配置分布式事务的一段原话:
配置分布式事务
要启用分布式事务,可能需要通过网络启用 MS DTC,以便在使用应用了最新的 Service Pack 的较新操作系统(例如 Windows XP 或 Windows 2003)时使用分布式事务。如果启用了 Windows 防火墙(Windows XP Service Pack 2 的默认设置),必须允许 MS DTC 服务使用网络或打开 MS DTC 端口。
实际怎么配置呢,经过我的实际使用:大致如下:打开'控制面板'->'管理工具'->'组件服务',点开'组件服务'->'计算机'->'我的电脑',在'我的电脑'上右击属性,点'MSDTC',然后点'安全性配置'。作为数据库的服务器的配置如下:

而访问数据库的客户端的配置和服务器端的稍有些差别:


在设置完上面的还有使防火墙MS DTC 服务使用网络或打开 MS DTC 端口:运行netsh firewall set allowedprogram %windir%/system32/msdtc.exe MSDTC enable命令就可以了

ASP.NET中的自动化事务 

    通过在ASP.NET页面中添加Transaction属性,可使得ASP.NET能够在系统中支持自动事务。利用Transaction属性,开发人员能够指示页面参与现有事务,开始新事务,或者不参与事务。下表列举了ASP.NET中可用的Transaction属性值。 

    通过在代码中的Page指令中设置Transaction属性能够定义页面支持的事务级别。例如,插入以下指令能够保证页面活动总是在事务范围中执行:

<%@ Page Transaction="Required" %>

如果省略Transaction属性,页面则禁用事务。使用System.EnterpriseServices.ContextUtil类的静态方法在ASP.NET页面中提交或者放弃事务。这些静态方法是SetComplete()和SetAbort()(它们分别对应Page事件CommitTransaction()和AbortTransaction())。以下代码列举了页面实现框架,该页面将Page指令的Transaction属性设置为Required,同时在CommitTransaction()和AbortTransaction()事件中,编写处理事务结果所需的代码。

  void Page_Load(object sender, System.EventArgs e)
{
AbortTransaction += new System.EventHandler(AbortTransactionEvent);
CommitTransaction += new System.EventHandler(CommitTransactionEvent);
try
{
/* 在这里放置事务性代码 */
ContextUtil.SetComplete();
}
catch (Exception)
{
ContextUtil.SetAbort();
}
}
void AbortTransactionEvent(object sender, System.EventArgs e)
{
/*用于回滚行为的代码*/
}
void CommitTransactionEvent(object sender, System.EventArgs e)
{
/*用于提交行为的代码*/
}
}

4. 何时使用事务 

    虽然.NET 2.0对事务提供了很好的支持,但是没有必要总是使用事务。使用事务的第一条规则是,在能够使用事务的时候都应该使用事务,但是不要使用过度。原因在于,每次使用事务,都会占用一定的开销。另外,事务可能会锁定一些表的行。还有一条规则是,只有当操作需要的时候才使用事务。例如,如果只是从数据库中查询一些记录,或者执行单个查询,在大部分时候都不需要使用显式事务。 

    开发人员应该在头脑中始终保持一个概念,就是用于修改多个不同表数据的冗长事务会严重妨碍系统中的所有其他用户。这很可能导致一些性能问题。当实现一个事务时,遵循下面的实践经验能够达到可接受的结果:(1)避免使用在事务中的SELECT返回数据,除非语句依赖于返回数据;(2)如果使用SELECT语句,只选择需要的行,这样不会锁定过多的资源,而尽可能的提高性能;(3)尽量将事务全部写在T-SQL或者API中;(4)避免事务与多重独立的批处理工作结合,应该将这些批处理放置在单独的事务中;(5)尽可能避免大量更新。 
另外,必须注意的一点就是事务的默认行为。在默认情况下,如果没有显式的提交事务,则事务会回滚。虽然默认行为允许事务的回滚,但是显式回滚方法总是一个良好的编程习惯。这不仅仅只是释放锁定数据,也将使得代码更容易读并且更少错误。

转载自:https://www.cnblogs.com/lgx5/p/7899929.html

.net 中的几种事务的更多相关文章

  1. SQL Server 中的6种事务隔离级别简单总结

    本文出处:http://www.cnblogs.com/wy123/p/7218316.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  2. .net中的4种事务总结

    在 一个MIS系统中,没有用事务那就绝对是有问题的,要么就只有一种情况:你的系统实在是太小了,业务业务逻辑有只要一步执行就可以完成了.因此掌握事务处 理的方法是很重要,进我的归类在.net中大致有以下 ...

  3. SpringMVC中的几种事务管理器

    转载https://blog.csdn.net/qq_26222859/article/details/52032853 1JDBC及iBATIS.MyBatis框架事务管理器 <bean id ...

  4. spring 中常用的两种事务配置方式以及事务的传播性、隔离级别

    一.注解式事务 1.注解式事务在平时的开发中使用的挺多,工作的两个公司中看到很多项目使用了这种方式,下面看看具体的配置demo. 2.事务配置实例 (1).spring+mybatis 事务配置 &l ...

  5. Java三大框架之——Hibernate中的三种数据持久状态和缓存机制

    Hibernate中的三种状态   瞬时状态:刚创建的对象还没有被Session持久化.缓存中不存在这个对象的数据并且数据库中没有这个对象对应的数据为瞬时状态这个时候是没有OID. 持久状态:对象经过 ...

  6. (转载)使用ADOConnet.BeginTrans后,出现错误提示:无法在此会话中启动更多的事务?

    Q: 三层结构,在服务器端使用adoconnection连接到sqlserver2000,然后想在 datasetprovider的beforupdaterecord中使用语句: try adocon ...

  7. SQL点滴9—SQL Server中的事务处理以及SSIS中的内建事务

    原文:SQL点滴9-SQL Server中的事务处理以及SSIS中的内建事务 我们可以把SSIS中的整个package包含在一个事务中,但是如果在package的执行过程中有一个表需要锁定应该怎么处理 ...

  8. Android编程中的5种数据存储方式

    Android编程中的5种数据存储方式 作者:牛奶.不加糖 字体:[增加 减小] 类型:转载 时间:2015-12-03我要评论 这篇文章主要介绍了Android编程中的5种数据存储方式,结合实例形式 ...

  9. j2ee中spring的分布式事务实现及解决方案

    1 java事务类型 Java事务的类型有三种:JDBC事务.JTA(Java Transaction API)事务.容器事务. 常见的容器事务如Spring事务,容器事务主要是J2EE应用服务器提供 ...

  10. 第七节: EF的三种事务的应用场景和各自注意的问题(SaveChanges、DBContextTransaction、TransactionScope)

    一. 什么是事务 我们通俗的理解事务就是一系列操作要么全部成功.要么全部失败(不可能存在部分成功,部分失败的情况). 举一个事务在我们日常生活中的经典例子:两张银行卡(甲.乙),甲向乙转钱,整个过程需 ...

随机推荐

  1. js-day02-综合案例ATM存款书写

     <script>                 // 1. 不断的弹出对话框         // 3. 金额的变量         let money = 100         w ...

  2. 【Java EE】Day12 XML、约束(DTD、Schema)、解析方式、Jsoup、选择器(Selector、XPath)

    一.XML介绍 1.概述 Extensible Markup Language--可扩展标记语言 标记语言 :标签构成 可扩展:可以自定义标签 2.功能 存储数据 作为配置文件使用 作为数据载体在网络 ...

  3. 看完这篇,还不懂JAVA内存模型(JMM)算我输

    欢迎关注专栏[JAVA并发] 更多技术干活尽在个人公众号--JAVA旭阳 前言 开篇一个例子,我看看都有谁会?如果不会的,或者不知道原理的,还是老老实实看完这篇文章吧. @Slf4j(topic = ...

  4. nvm下升级npm版本

    1 3445 error path C:\Users\xxx\AppData\Roaming\nvm\v12.18.3\npm.cmd 2 3446 error Refusing to delete ...

  5. 基于U-Net网络的图像分割的MindStudio实践

    摘要:本实践是基于Windows版MindStudio 5.0.RC3,远程连接ECS服务器使用,ECS是基于官方分享的CANN6.0.RC1_MindX_Vision3.0.RC3镜像创建的. 本文 ...

  6. [seaborn] seaborn学习笔记10-绘图实例(2) Drawing example(2)

    文章目录 10 绘图实例(2) Drawing example(2) 1. Grouped violinplots with split violins(violinplot) 2. Annotate ...

  7. Shell 基本常识

    Shell 进入命令行 启动 shell 常用命令 系统管理命令 处理数据命令 Linux 基础管理命令 用户管理 管理文件系统 软件包管理系统 使用容器管理软件 理解 shell 子 shell 环 ...

  8. Mac对文件夹加密

    一.打开磁盘工具 电脑左上角文件->新建映像->基于文件夹新建映像->选择相对应的文件夹,进行aes加密->输入加密密码 然后保存文件就好了

  9. Hugging News #0106

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  10. ionic+vue+capacitor系列笔记--手机从安卓10升级到安卓11以后,之前的代码不管用了,无法跳转其他应用

    之前手机是安卓10版本,没什么问题,升级以后,手机出现了一些异常,发现原来代码里写的跳转功能,无法使用了哦~~脑壳痛 解决方案 本项目:build.gradle targetSdkVersion 30 ...