.NET事务应用原则

1.在同一个数据库内进行CRUD时,应使用同一个DbConnection对象,且显式指定DbConnection均为同一个DbTransaction,示例代码如下:

//在同一个DB中操作一个表时,可以不用显式指定事务,因为单条SQL命令就是一个最小的事务单元
using (DbConnection conn = new SqlConnection("数据库连接字符串"))
{
var cmd = conn.CreateCommand();
cmd.CommandText = "delete users";
cmd.ExecuteNonQuery();
} //在同一个DB中操作多个表或执行不同的SQL命令时,需要显式指定事务,且需确保每个Command均与同一个DbTransaction关联
using (DbConnection conn = new SqlConnection("数据库连接字符串"))
{
DbTransaction tran = conn.BeginTransaction();
try
{
var cmd = conn.CreateCommand();
cmd.Transaction = tran;
cmd.CommandText = "delete users";
cmd.ExecuteNonQuery(); var cmd2 = conn.CreateCommand();
cmd2.Transaction = tran;
cmd2.CommandText = "delete roles";
cmd2.ExecuteNonQuery(); tran.Commit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
tran.Rollback();
}
}

2.在同一个服务器上的不同数据库之间进行CRUD时,应使用同一个DbConnection对象,且显式指定DbConnection均为同一个DbTransaction,同时SQL命令语句中的包含的对象(表、视图、存储过程、函数等)应显式指定数据库名称,格式如:databasename.owner.tablename,如:Db1.dbo.Users;Db2.dbo.Users;(前提条件:多个数据库的用户名及密码相同的情况下,否则就只能使用分布式事务),示例代码如下:

//在同一个Server不同的DB中操作多个表或执行不同的SQL命令时,需要显式指定事务,且需确保每个Command均与同一个DbTransaction关联,CommandText还应显式添加数据库名称
using (DbConnection conn = new SqlConnection("数据库连接字符串"))
{
DbTransaction tran = conn.BeginTransaction();
try
{
var cmd = conn.CreateCommand();
cmd.Transaction = tran;
cmd.CommandText = "delete db1.dbo.users";
cmd.ExecuteNonQuery(); var cmd2 = conn.CreateCommand();
cmd2.Transaction = tran;
cmd2.CommandText = "delete db2.dbo.roles";
cmd2.ExecuteNonQuery(); tran.Commit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
tran.Rollback();
}
}

3.在不同的DB服务器上进行CRUD时,应使用分布式事务,可以采取隐式或显式开启分布式事务,示例代码如下:

//采用隐式开启分布式事务
using (TransactionScope tranScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
using (DbConnection conn = new SqlConnection("数据库连接字符串"))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "delete users";
cmd.ExecuteNonQuery();
} using (DbConnection conn2 = new SqlConnection("数据库连接字符串2"))
{
conn2.Open();
var cmd2 = conn2.CreateCommand();
cmd2.CommandText = "delete users";
cmd2.ExecuteNonQuery();
}
tranScope.Complete();
} //采用显式开启分布式事务
using (CommittableTransaction committableTransaction = new CommittableTransaction())
{
try
{
using (DbConnection conn = new SqlConnection("数据库连接字符串"))
{
conn.Open();
conn.EnlistTransaction(committableTransaction); //将连接登记到可提交事务
var cmd = conn.CreateCommand();
cmd.CommandText = "delete users";
cmd.ExecuteNonQuery();
} using (DbConnection conn2 = new SqlConnection("数据库连接字符串2"))
{
conn2.Open();
conn2.EnlistTransaction(committableTransaction); //将连接登记到可提交事务
var cmd2 = conn2.CreateCommand();
cmd2.CommandText = "delete users";
cmd2.ExecuteNonQuery();
} committableTransaction.Commit();
}
catch (Exception ex)
{
committableTransaction.Rollback(ex);
}
} //采用显式开启分布式事务,模拟TransactionScope用法的过程
{
Transaction originalTransaction = Transaction.Current; //记录当前的环境事务,用于后面的恢复
CommittableTransaction committableTransaction = null;
DependentTransaction dependentTransaction = null;
committableTransaction = new CommittableTransaction();
Transaction.Current = committableTransaction;//将定义的可提交事务作为当前的环境事务 try
{ using (DbConnection conn = new SqlConnection("数据库连接字符串"))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "delete users";
cmd.ExecuteNonQuery();
} dependentTransaction = Transaction.Current.DependentClone(DependentCloneOption.RollbackIfNotComplete); //复制当前的环境事务从而产生新的依赖事务,且指定必需等到该事务完成
Transaction.Current = dependentTransaction;//将复制到的新的依赖事务 using (DbConnection conn2 = new SqlConnection("数据库连接字符串2"))
{
conn2.Open();
var cmd2 = conn2.CreateCommand();
cmd2.CommandText = "delete users";
cmd2.ExecuteNonQuery();
} dependentTransaction.Complete();
committableTransaction.Commit();
}
catch (Exception ex)
{
Transaction.Current.Rollback(ex);
}
finally //不论成功与否,最终都将恢复成原来的环境事务
{
Transaction transaction = Transaction.Current;
Transaction.Current = originalTransaction;
transaction.Dispose();
} }

最终总结一下:

1.查询无需事务;

2.涉汲执行增、删、改的SQL命令时,应考虑是否需要确保执行数据的一致性,若需要则必需使用事务,否则可以采取默认方式;

3.在同一个DB服务器中,尽可能的使用本地事务,跨多个DB服务器中,需要使用分布式事务;

4.尽可能的缩小事务的使用范围,避免出现多层级的嵌套事务;

5.若需要使用分布式事务,在WINDOWS下需要开启MS DTC服务(分布式事务管理器)

简述.NET事务应用原则的更多相关文章

  1. 一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)

    这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 1.简述Redis事务实现 2.redis集群方案 3.redis主从复制的核心原理 4.CAP理论,BASE理论 5.负 ...

  2. 数据库ACID操作---事务四原则

    事务操作四原则: 1>原子性:简单来说——整个事务操作如同原子已经是物理上最小的单位,不可分离事务操作要么一起成功,要么一起失败. 2>一致性:倘若事务操作失败,则回滚事务时,与原始状态一 ...

  3. 简述Spring事务有几种管理方法,写出一种配置方式

    Spring事务有两种方式: 1.编程式事务:(代码中嵌入) 2.声明式事务:(注解,XML) 注解方式配置事务的方式如下: 首先,需要在applicationContext.xml中添加启动配置,代 ...

  4. [高性能MYSQL 读后随笔] 关于事务的隔离级别(一)

    一.锁的种类 MySQL中锁的种类很多,有常见的表锁和行锁,也有新加入的Metadata Lock等等,表锁是对一整张表加锁,虽然可分为读锁和写锁,但毕竟是锁住整张表,会导致并发能力下降,一般是做dd ...

  5. 【mysql】关于事务的隔离级别

    一.锁的种类 MySQL中锁的种类很多,有常见的表锁和行锁,也有新加入的Metadata Lock等等,表锁是对一整张表加锁,虽然可分为读锁和写锁,但毕竟是锁住整张表,会导致并发能力下降,一般是做dd ...

  6. 《高性能MySQL》读书笔记--锁、事务、隔离级别 转

    1.锁 为什么需要锁?因为数据库要解决并发控制问题.在同一时刻,可能会有多个客户端对表中同一行记录进行操作,比如有的在读取该行数据,其他的尝试去删除它.为了保证数据的一致性,数据库就要对这种并发操作进 ...

  7. Spring分布式事务实现概览

    分布式事务,一直是实现分布式系统过程中最大的挑战.在只有单个数据源的单服务系统当中,只要这个数据源支持事务,例如大部分关系型数据库,和一些MQ服务,如activeMQ等,我们就可以很容易的实现事务. ...

  8. .NET:分布式事务

    背景 分布式事务使用起来比较方便,不过也是有成本的,因此如果可以不用就尽量不用,比如:采用saga.如果采用了分布式事务的话,就需要对分布式事务相关的几个概念有所了解. 分布式事务 相关角色: 事务发 ...

  9. 07_Redis事务

    [简述] 事务是指一系列的操作步骤,着一些列的操作步骤,要么完全地执行,要不完全地不执行. 比如微博中: A用户关注了B用户,那么A的关注列表里就会有B用户,B用户的粉丝列表里就会有A用户. 这个关注 ...

随机推荐

  1. Unity3D游戏开发初探—1.跨平台的游戏引擎让.NET程序员新生

    一.Unity3D平台简介 Unity是由Unity Technologies开发的一个让轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的 ...

  2. 我的LESS编译方案

    背景 近期项目前端决定使用less,简单介绍一下,详细信息有兴趣查看官方文档(http://www.lesscss.net/article/home.html) LESSCSS是一种动态样式语言,属于 ...

  3. CSS3 Animation制作飘动的浮云和星星效果

    带平行视差效果的星星 先看效果: 如果下方未出现效果也可前往这里查看 http://sandbox.runjs.cn/show/0lz3sl9y 下面我们利用CSS3的animation写出这样的动画 ...

  4. EF:自定义Oracle的映射类型

    oracle在DB First模式下,int类型的字段会自动映射为decmial类型的属性. 我们可以通过自定义类型映射进行“纠整”. 在app.config 自定义映射规则: <oracle. ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (15) -----第三章 查询之与列表值比较和过滤关联实体

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-8与列表值比较 问题 你想查询一个实体,条件是给定的列表中包含指定属性的值. 解 ...

  6. 《Entity Framework 6 Recipes》中文翻译系列 (21) -----第四章 ASP.NET MVC中使用实体框架之在页面中创建查询和使用ASP.NET URL路由过虑

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 4.2. 构建一个搜索查询 搜索数据是几乎所有应用的一个基本功能.它一般是动态的,因 ...

  7. Objective-C 观察者模式--简单介绍和使用

    观察者模式(有时又被称为发布-订阅模式) 在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知. 这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来实 ...

  8. sublime3 插件

    Sublime Text 3能用支持的插件推荐 从二月份用测试版本build 3012开始用sublime text 3,虽然很多插件在sublime text 3不工作了,因为sublime tex ...

  9. WPF入门教程系列十七——WPF中的数据绑定(三)

    四. XML数据绑定 这次我们来学习新的绑定知识,XML数据绑定.XmlDataProvider 用来绑定 XML 数据,该XML数据可以是嵌入.Xmal文件的 XmlDataProvider 标记中 ...

  10. 单页面实现之hash

    至学了angularJs后,发现这个单页面应用不知道在没有angularJs的情况下怎么实现. 所以就此对这个思考与资料并行,终于知道这个的实现基本原理. 首先angularJs的实现是hash值的变 ...