一、基础知识

1)         使用事务级别ReadUnCommited 会产生脏读现像,意味着读取到的为UnCommited(未提交)的数据。怎么理解呢?在使用该隔离级别的事务开始后。更新了数据库某一行的数据,但是事务的工作量比较大,后续还有一大堆代码还没执行完呢。不巧的是有个哥们过来读数据了,这个时候读到的就是未提交的值,如果后继工作一切正常,也没什么影响。一旦后面的代码执行中出错,就会产生不一致的错误,适用于对事务极度自信的情况下,特点为可读不可改。关于不可改需解释一下,MS SQL中一条语句为最基本的执行单元了,如果一个事务中,对同条数据的更新语句未Commited的情况下,其它事务是需要等待的。

2)         使用事务级别ReadCommited 会消除脏读现像,意味着读取到的为Commited(已提交)的数据。在使用该隔离级别的事务开始后,除了该事务其它的查询均会一直等待直到该事务提交。特点为不可读不可改,

3)         使用事务级别Repeatable Read,可重复读。它不会像ReadCommited一样阻止Select查询,但它会阻止Update语句。使用该隔离级别的事务开始后,会阻止其它事务更改查询。但依然可以新增数据。

4)         使用事务级别Serializable 最严的一种了,与Repeatable Read相比就是在这种级别下不能新增数据。

5)         下表为简单说明

其中增删除改查为其它事务中对已在事务中的数据行进行增删改查的可能行性,其中删,改,查操作多个事务中的同一条数据。√指该隔离级别下操作可未被阻塞可立即响应。

隔离级别

增(其他事务)

删(其他事务)

改(其他事务)

查(其他事务)

脏读

读提交

可重复读

幻影读

数据过期

ReadUnCommited

×

×

×

×

ReadCommited

×

×

×

×

×

×

Repeatable Read

×

×

×

Serializable

×

×

×

×

×

二、C#中的事务

1)         ADO.NET中的事务与EF中的事务,它们是一类事物。可以说是同一个东西,均为封装了 SQL语句中的 Begin Tran Commit等。

2)         分布式事务TranscationCope需引用System.data.Transcations.dll才能使用

3)         分布式事务与事务二者区别,主要区别在于前者用于一个数据连接中控制数据一致性,后者在多个数据库连接中控制数据一致性,如果不能理解,可以记忆为一个数据库使用事务用前者,多个数据库中使用事务用后者,如果在一个数据连接中使用TranscationCope,可以把它为理解为简化版的事务,因为它只有Complete方法。

4)         注意TranscationCope进行多事务协调时需安装与设置MSDTC组件。

5)         并行事务:指在同一个DBConnection中启用二个事务,这个不被ADO.NET与EF支持(目前),如果程序运行过程中出现了 Connection不支持并行事务的时候,检查一下是否在一个数据库连接中使用了二个事务。

三、事务的应用与验证。

1)         下面依次验证(末完成)

  验证时注意事项:连接字符串中设置 Pooling = False 既关掉数据连接池,特别是多次测试之后会有点小问题干扰结论。;如果需要验证多个事务进行引发的异常还是阻塞进程,需要把超时时间设置为更多一些超过程序预计运行时间。EF建议大家使用EF6.0,在低版本的 EF 中不能指定SaveChanges时使用的事务。

验证时使用3个线程向同一表中插入10条数据,如果顺序插入,表明事务是顺序执行,下面上代码

    class Program
{
static string connectionString = "server=127.0.0.1;database=xxxxxx;user=sa;password=xxxxxx;Pooling=False";
static System.Data.IsolationLevel tranLevel = System.Data.IsolationLevel.ReadUncommitted;
static string commandText = "update [Locker] set [id] = 100" ; static void Main(string[] args)
{
ClearTestData();
tranLevel = System.Data.IsolationLevel.ReadUncommitted;
commandText = "update [Locker] set [id] = 100";
Thread th1 = new Thread(new ThreadStart(() =>
{
test();
})); Thread th2 = new Thread(new ThreadStart(() =>
{
test(); }));
Thread th3 = new Thread(new ThreadStart(() =>
{
test(); }));
th1.Name = "线程1";
th2.Name = "线程2";
th3.Name = "线程3";
th2.Start();
th3.Start();
th1.Start();
Console.ReadLine();
} static void test()
{
using (var db = new SupplierPortalEntities())
{
var connection = db.Database.Connection;
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
var tran = connection.BeginTransaction(tranLevel);
try
{
db.Database.UseTransaction(tran);
var command = commandText;
db.Database.ExecuteSqlCommand(command); for (int i = 0; i < 20; i++)
{
Random r = new Random();
var t = new TranLocker();
t.Content = Thread.CurrentThread.Name;
db.TranLocker.Add(t);
Console.WriteLine("线程{0}加入数据 - lockid: {1}", Thread.CurrentThread.Name, t.LockID);
Thread.Sleep(50);
}
db.SaveChanges();
//if (Thread.CurrentThread.Name.EndsWith("3")) //引发一个异常 .
//{
// throw new Exception("3为故障码");
//}
tran.Commit();
Console.WriteLine("线程{0}:事务已提交", Thread.CurrentThread.Name);
}
catch (Exception er)
{
tran.Rollback();
Console.WriteLine("线程{0}:发生错误,事务已回滚:{1}", Thread.CurrentThread.Name, er.Message);
}
}
} static void ClearTestData()
{
//清除数据
var connClearInsertDatas = new SqlConnection(connectionString);
connClearInsertDatas.Open();
var cmd = connClearInsertDatas.CreateCommand();
cmd.CommandText = "delete from TranLocker";
cmd.ExecuteNonQuery();
connClearInsertDatas.Close();
}
}

  

数据库事务及其EF中如何处理事务的更多相关文章

  1. Entity Framework入门教程(19)---EF中使用事务

    EF中使用事务 这节介绍EF6中事务的使用.EF core中事务的使用方式和EF6中一模一样. 1.EF中的默认的事务 默认情况下,当我们执行一个SaveChanges()方法时就会新建了一个事务,然 ...

  2. 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系

    重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...

  3. 事务的隔离级别,mysql中开启事务、django中开启事务

    目录 一.事务的特性 二.数据库中开启事务 三.Django中开启事务的两种方式 第一种 第二种 四.事务的隔离级别 隔离级别 如何查看mysql隔离级别? 修改事务的隔离级别 隔离级别解释 read ...

  4. EF中使用事务

    using (var db = new dbEntities()) { //第一个坑,需要手动open db.Database.Connection.Open(); using (var tran = ...

  5. 事务——sql server中的事务应用举例

    sql中事务只针对一个update,delete,insert语句,如果一段程序中有超过一个这样的语句,就需要每个都判断是否出错,否则就会出现若干我们不希望的情形出现,举例如下(表结构见最后): 1, ...

  6. 阶段3 1.Mybatis_07.Mybatis的连接池及事务_6 mybatis中的事务原理和自动提交设置

    在实际的开发中,建议使用连接池的形式. JNDI的资料 H:\BaiDu\黑马传智JavaEE57期 2019最新基础+就业+在职加薪\讲义+笔记+资料\主流框架\31.会员版(2.0)-就业课(2. ...

  7. 在EF中正确的使用事务

    1.EF中使用事务: using (TransactionScope tran = new TransactionScope()) { try { using(var _context = new D ...

  8. 代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性

    做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线.真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程( ...

  9. 一步步学习EF Core(2.事务与日志)

    前言 上节我们留了一个问题,为什么EF Core中,我们加载班级,数据并不会出来 其实答案很简单,~ 因为在EF Core1.1.2 中我们在EF6.0+中用到的的延迟加载功能并没有被加入,不过在EF ...

随机推荐

  1. NodeJS学习笔记 (14)URL查询字符串-querystring(ok)

    模块概述 在nodejs中,提供了querystring这个模块,用来做url查询参数的解析,使用非常简单. 模块总共有四个方法,绝大部分时,我们只会用到 .parse(). **.stringify ...

  2. 洛谷P1280 && caioj 1085 动态规划入门(非常规DP9:尼克的任务)

    这道题我一直按照往常的思路想 f[i]为前i个任务的最大空暇时间 然后想不出来怎么做-- 后来看了题解 发现这里设的状态是时间,不是任务 自己思维还是太局限了,题做得太少. 很多网上题解都反着做,那么 ...

  3. socket 编程的端口和地址复用

    在linux socket网络编程中,大规模并发TCP或UDP连接时,经常会用到端口复用:   int opt = 1;   if(setsockopt(sockfd, SOL_SOCKET,SO_R ...

  4. HDFS 断点续传,写文件功能

    实际上这是个 HDFS 的工具类部分代码. 首先 public static Configuration configuration = null;public static FileSystem f ...

  5. Android——4.2 - 3G移植之路之 APN (五)

    APN,这东西对于刚接触的人来说并非那么好理解.对于3G移植上网不可缺少,这里记录一下. 撰写不易,转载请注明出处:http://blog.csdn.net/jscese/article/detail ...

  6. Linux打包免安装的Qt程序(编写导出依赖包的脚本copylib.sh,程序启动脚本MyApp.sh)

    本文介绍如何打包Qt程序,使其在没有安装Qt的系统可以运行. 默认前提:另外一个系统和本系统是同一个系统版本. 1,编写导出依赖包的脚本copylib.sh #!/bin/bash LibDir=$P ...

  7. Spring security工作流程及集成

    A user enters their username and password into a login screen and clicks a login button. The entered ...

  8. JAVA线程队列BlockingQueue

    JAVA线程队列BlockingQueue 介绍 BlockingQueue阻塞队列,顾名思义,首先它是一个队列,通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出. 常用的队列主要有以 ...

  9. [ Linux ] 釋放記憶體指令(cache) - 轉載

    1. [Linux]釋放記憶體指令(cache) http://jeffreyy.pixnet.net/blog/post/84333764-%E3%80%90linux%E3%80%91%E9%87 ...

  10. javaScript 三目运算符初探

    三目运算符 三目运算符,又称条件运算符,是计算机语言的重要组成部分.它是唯一有3个操作数的运算符,所以有时又称为三元运算符.一般来说,三目运算符的结合性是右结合的. 定义 对于条件表达式b ? x : ...