一、基础知识

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. CMD和AMD的区别

    CMD和AMD俩者之间的区别 AMD和CMD最大的区别是对依赖模块的执行时机处理不同 CMD和AMD都是CommonJS延伸而来的,CommonJS是随着node的出现而出现的,它是一个规范,用于定义 ...

  2. [洛谷P3929]SAC E#1 - 一道神题 Sequence1

    题目大意:给你一串数列,问你能否改变1个数或不改,使它变成波动数列? 一个长度为n的波动数列满足对于任何i(1 <= i < n),均有: a[2i-1] <= a[2i] 且 a[ ...

  3. 洛谷——P1965 转圈游戏

    https://www.luogu.org/problem/show?pid=1965 题目描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n- ...

  4. 洛谷 P1769 淘汰赛制_NOI导刊2010提高(01)

    P1769 淘汰赛制_NOI导刊2010提高(01) 题目描述 淘汰赛制是一种极其残酷的比赛制度.2n名选手分别标号1,2,3,…,2^n-1,2^n,他们将要参加n轮的激烈角逐.每一轮中,将所有参加 ...

  5. List和iterator的区别

    (1)在用Query方法查询的时候,通过HQL语句来得到Query对象,并对Query对象进行操作,首先是用list方法获取到Query的List集合并输出 public void listQuery ...

  6. 翻翻git之---炫酷的自己定义翻滚View TagCloudView

    转载请注明出处:王亟亟的大牛之路 周一好,又到了每周最困的一天.近期都被啮齿类动物搞的累死,废话不多,今天上一个自己定义的ViewGroup实现一个3D球形集合. 效果图: 效果还不错,能够作为短小文 ...

  7. 英语影视台词---三、Cinema Paradiso

    英语影视台词---三.Cinema Paradiso 一.总结 一句话总结:天堂电影院 1.Alfredo: No, Toto. Nobody said it. This time it's all ...

  8. 打开文件对话框在xp和win7上的实现文件任意多选

    作者:朱金灿 来源:http://blog.csdn.net/clever101 在xp系统上进行文件多选,实际上其文件字符串数组的缓冲区是有限,并不能支持选择任意多个文件,为此以前我还写过一篇文章: ...

  9. SQLite: sqlite_master(转)

    转自:http://blog.sina.com.cn/s/blog_6afeac500100yn9k.html SQLite数据库中一个特殊的名叫 SQLITE_MASTER 上执行一个SELECT查 ...

  10. Linux常用截图软件

    1.Gnome-screenshot 是一款 GNOME 截图工具,顾名思义,它是一款用来对整个屏幕.一个特定的窗口或者用户所定义一些其他区域进行捕获的工具.该工具提供了几个其他的功能,包括对所捕获的 ...