.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. 基于struts2和hibernate的分页实现

    在拜读了各位大牛的博客后,加以修改和添加总算是借鉴出了一个可行的分页实现.(●'◡'●) 话不多说,先贴两张效果图吧 接下来是实现代码: pagingDAOImpl.java public class ...

  2. 让代码重构渐行渐远系列(3)——string.Equals取代直接比较与非比较

    重构背景及原因 最近由于项目组的人员在不断扩充,导致项目中代码风格各异,大有百花齐放甚至怒放之势.考虑到团队的生存与发展,经过众人多次舌战之后,最终决定项目组根据业务分成几个小分队,以加强团队管理与提 ...

  3. Raft 为什么是更易理解的分布式一致性算法

    一致性问题可以算是分布式领域的一个圣殿级问题了,关于它的研究可以回溯到几十年前. 拜占庭将军问题 Leslie Lamport 在三十多年前发表的论文<拜占庭将军问题>(参考[1]). 拜 ...

  4. C#获取本机可用端口

    当我们要创建一个Tcp/UDP Server connection ,我们需要一个范围在1000到65535之间的端口 .但是本机一个端口只能一个程序监听,所以我们进行本地监听的时候需要检测端口是否被 ...

  5. 你的应用是如何被替换的,App劫持病毒剖析

    一.App劫持病毒介绍 App劫持是指执行流程被重定向,又可分为Activity劫持.安装劫持.流量劫持.函数执行劫持等.本文将对近期利用Acticity劫持和安装劫持的病毒进行分析. 二.Activ ...

  6. Qt Disable QDebug And Warning Output

    如何禁止qDebug的输出 在项目开发的过程中,为了开发方便,我们常常在Qt的Application Output中输出一些内容,慢慢的. 有些qDebug就会被我们遗忘再角落里. 虽然对整个程序影响 ...

  7. Html5 绘制旋转的太极图

    采用Html5+JavaScript在Canvas中绘制旋转的太极图,如下图所示: 具体思路和绘制逻辑,在上图中已有说明,代码如下: <script type="text/javasc ...

  8. LinuxThreads 和 NPTL

    http://www.ibm.com/developerworks/cn/linux/l-threading.html Linux 线程模型的比较:LinuxThreads 和 NPTL 进行移植的开 ...

  9. 监控Linux系统性能的工具--nmon(一)

    今天看到一资料上写着,nmon可以对linux系统进行性能监控,随手在自己的阿里云上敲了一下这个命令,提示'command not find' 一脸懵~,然后探索了一下如何安装这个工具以及如何更好的查 ...

  10. Leetcode-24 Swap Nodes in Pairs

    #24. Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. For ...