1、TransactionScope代码事务
TransactionScope 类

位于using System.Transactions;命名空间下,需要在引用中手动加入。该类不能被继承。

   //// 摘要://     使代码块成为事务性代码。此类不能被继承。public sealed class TransactionScope : IDisposable

常用参数

1.TransactionScopeOption

//
// 摘要:
//     该范围需要一个事务。如果已经存在环境事务,则使用该环境事务。否则,在进入范围之前创建新的事务。这是默认值。
Required = 0,
//
// 摘要:
//     总是为该范围创建新事务。
RequiresNew = 1,
//
// 摘要:
//     环境事务上下文在创建范围时被取消。范围中的所有操作都在无环境事务上下文的情况下完成。
Suppress = 2

2.TimeSpan设置超时时间

//// 摘要://     以指定的超时时间值和要求初始化 System.Transactions.TransactionScope 类的新实例。//// 参数://   scopeOption://     System.Transactions.TransactionScopeOption 枚举的一个实例,描述与此事务范围关联的事务要求。////   scopeTimeout://     在 System.TimeSpan 之后,事务范围将超时并中止此事务。public TransactionScope(TransactionScopeOption scopeOption, TimeSpan scopeTimeout);

优点:

1、使用起来比较方便.TransactionScope可以实现隐式的事务,使你可以在写数据访问层代码的时候不用考虑到事务,而在业务层的控制事务.

2、可以实现分布式事务,比如跨库或MSMQ.

3.在EntityFramework中可以解决DbContextTransaction的多个上下文出现死锁问题。也就是说在EF中使用TransactionScope事务时,不用考虑数据库操作的多上下文问题。

缺点:

1.此中方式对于数据库锁定表,会影响其他进程的查询,也就是对于锁定的表,查询也锁定,不允许出现脏读,其他的查询需要挂起等待。重点是不能进行配置修改。

2.此中方式对于同一个范围/同一个逻辑操作,需要进行多线程的锁定处理,不然多个线程开启同一个事务会抛出异常。

3.多个事务操作中,存在锁定同一个表的时候也会出现死锁现象

参考:https://blog.csdn.net/u011127019/article/details/53940402

2、数据库事务

什么是事务(Transaction)?

是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

举个例子加深一下理解:同一个银行转账,A转1000块钱给B,这里存在两个操作,一个是A账户扣款1000元,两一个操作是B账户增加1000元,两者就构成了转账这个事务。

  • 两个操作都成功,A账户扣款1000元,B账户增加1000元,事务成功
  • 两个操作都失败,A账户和B账户金额都没变,事务失败

最后思考一下,怎么样会出现A账户扣款1000元,B账户金额不变?如果你是把两个操作放在一个事务里面,并且是数据库提供的内在事务支持,那就不会有问题,但是开发人员把两个操作放在两个事务里面,而第二个事务失败就会出现中间状态。现实中自己实现的分布式事务处理不当也会出现中间状态,这并不是事务的错,事务本身就是规定不会出现中间状态,是事务实现者做出来的方案有问题。

事务的4个特性

  • 原子性(Atomic):事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。通常,与某个事务关联的操作具有共同的目标,并且是相互依赖的。如果系统只执行这些操作的一个子集,则可能会破坏事务的总体目标。原子性消除了系统处理操作子集的可能性。

  • 一致性(Consistency):事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。这种特性称为事务的一致性。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的。

  • 隔离性(Isolation):由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,到底是另一个事务执行之前的状态还是中间某个状态,相互之间存在什么影响,是可以通过隔离级别的设置来控制的。

  • 持久性(Durability):事务结束后,事务处理的结果必须能够得到固化,即写入数据库文件中即使机器宕机数据也不会丢失,它对于系统的影响是永久性的。

事务并发控制

我们从另外一个方向来说说,如果不对事务进行并发控制,我们看看数据库并发操作是会有那些异常情形,有些使我们可以接受的,有些是不能接受的,注意这里的异常就是特定语境下的,并不一定就是错误什么的。假设有一个order表,有个字段叫count,作为计数用,当前值为100

  • 第一类丢失更新(Update Lost):此种更新丢失是因为回滚的原因,所以也叫回滚丢失。此时两个事务同时更新count,两个事务都读取到100,事务一更新成功并提交,count=100+1=101,事务二出于某种原因更新失败了,然后回滚,事务二就把count还原为它一开始读到的100,此时事务一的更新就这样丢失了。

  • 脏读(Dirty Read):此种异常时因为一个事务读取了另一个事务修改了但是未提交的数据。举个例子,事务一更新了count=101,但是没有提交,事务二此时读取count,值为101而不是100,然后事务一出于某种原因回滚了,然后第二个事务读取的这个值就是噩梦的开始。

  • 不可重复读(Not Repeatable Read):此种异常是一个事务对同一行数据执行了两次或更多次查询,但是却得到了不同的结果,也就是在一个事务里面你不能重复(即多次)读取一行数据,如果你这么做了,不能保证每次读取的结果是一样的,有可能一样有可能不一样。造成这个结果是在两次查询之间有别的事务对该行数据做了更新操作。举个例子,事务一先查询了count,值为100,此时事务二更新了count=101,事务一再次读取count,值就会变成101,两次读取结果不一样。

  • 第二类丢失更新(Second Update Lost):此种更新丢失是因为更新被其他事务给覆盖了,也可以叫覆盖丢失。举个例子,两个事务同时更新count,都读取100这个初始值,事务一先更新成功并提交,count=100+1=101,事务二后更新成功并提交,count=100+1=101,由于事务二count还是从100开始增加,事务一的更新就这样丢失了。

  • 幻读(Phantom Read):幻读和不可重复读有点像,只是针对的不是数据的值而是数据的数量。此种异常是一个事务在两次查询的过程中数据的数量不同,让人以为发生幻觉,幻读大概就是这么得来的吧。举个例子,事务一查询order表有多少条记录,事务二新增了一条记录,然后事务一查了一下order表有多少记录,发现和第一次不一样,这就是幻读。

数据库事务隔离级别

看到上面提到的几种问题,你可能会想,我擦,这么多坑怎么办啊。其实上面几种情况并不是一定都要避免的,具体看你的业务要求,包括你数据库的负载都会影响你的决定。不知道大家发现没有,上面各种异常情况都是多个事务之间相互影响造成的,这说明两个事务之间需要某种方式将他们从某种程度上分开,降低直至避免相互影响。这时候数据库事务隔离级别就粉墨登场了,而数据库的隔离级别实现一般是通过数据库锁实现的。

  • 读未提交(Read Uncommitted):该隔离级别指即使一个事务的更新语句没有提交,但是别的事务可以读到这个改变,几种异常情况都可能出现。极易出错,没有安全性可言,基本不会使用。

  • 读已提交(Read Committed):该隔离级别指一个事务只能看到其他事务的已经提交的更新,看不到未提交的更新,消除了脏读和第一类丢失更新,这是大多数数据库的默认隔离级别,如Oracle,Sqlserver。

  • 可重复读(Repeatable Read):该隔离级别指一个事务中进行两次或多次同样的对于数据内容的查询,得到的结果是一样的,但不保证对于数据条数的查询是一样的,只要存在读改行数据就禁止写,消除了不可重复读和第二类更新丢失,这是Mysql数据库的默认隔离级别。(事务A在执行前,分析其中要读取的所有item,然后将这些item都设置读+写排它锁,等事务执行完再释放)

  • 串行化(Serializable):意思是说这个事务执行的时候不允许别的事务并发执行.完全串行化的读,只要存在读就禁止写,但可以同时读,消除了幻读。这是事务隔离的最高级别,虽然最安全最省心,但是效率太低,一般不会用。

下面是各种隔离级别对各异常的控制能力:

级别\异常 第一类更新丢失 脏读 不可重复读 第二类丢失更新 幻读
读未提交 Y Y Y Y Y
读已提交 N N Y Y Y
可重复读 N N N N Y
串行化 N N N N N

数据库锁分类

一般可以分为两类,一个是悲观锁,一个是乐观锁,悲观锁一般就是我们通常说的数据库锁机制,乐观锁一般是指用户自己实现的一种锁机制,比如hibernate实现的乐观锁甚至编程语言也有乐观锁的思想的应用。

悲观锁:顾名思义,就是很悲观,它对于数据被外界修改持保守态度,认为数据随时会修改,所以整个数据处理中需要将数据加锁。悲观锁一般都是依靠关系数据库提供的锁机制,事实上关系数据库中的行锁,表锁不论是读写锁都是悲观锁。

悲观锁按照使用性质划分:

  • 共享锁(Share locks简记为S锁):也称读锁,事务A对对象T加s锁,其他事务也只能对T加S,多个事务可以同时读,但不能有写操作,直到A释放S锁。

  • 排它锁(Exclusivelocks简记为X锁):也称写锁,事务A对对象T加X锁以后,其他事务不能对T加任何锁,只有事务A可以读写对象T直到A释放X锁。

  • 更新锁(简记为U锁):用来预定要对此对象施加X锁,它允许其他事务读,但不允许再施加U锁或X锁;当被读取的对象将要被更新时,则升级为X锁,主要是用来防止死锁的。因为使用共享锁时,修改数据的操作分为两步,首先获得一个共享锁,读取数据,然后将共享锁升级为排它锁,然后再执行修改操作。这样如果同时有两个或多个事务同时对一个对象申请了共享锁,在修改数据的时候,这些事务都要将共享锁升级为排它锁。这些事务都不会释放共享锁而是一直等待对方释放,这样就造成了死锁。如果一个数据在修改前直接申请更新锁,在数据修改的时候再升级为排它锁,就可以避免死锁。

悲观锁按照作用范围划分:

  • 行锁:锁的作用范围是行级别,数据库能够确定那些行需要锁的情况下使用行锁,如果不知道会影响哪些行的时候就会使用表锁。举个例子,一个用户表user,有主键id和用户生日birthday当你使用update … where id=?这样的语句数据库明确知道会影响哪一行,它就会使用行锁,当你使用update … where birthday=?这样的的语句的时候因为事先不知道会影响哪些行就可能会使用表锁。
  • 表锁:锁的作用范围是整张表。

乐观锁:顾名思义,就是很乐观,每次自己操作数据的时候认为没有人回来修改它,所以不去加锁,但是在更新的时候会去判断在此期间数据有没有被修改,需要用户自己去实现。既然都有数据库提供的悲观锁可以方便使用为什么要使用乐观锁呢?对于读操作远多于写操作的时候,大多数都是读取,这时候一个更新操作加锁会阻塞所有读取,降低了吞吐量。最后还要释放锁,锁是需要一些开销的,我们只要想办法解决极少量的更新操作的同步问题。换句话说,如果是读写比例差距不是非常大或者你的系统没有响应不及时,吞吐量瓶颈问题,那就不要去使用乐观锁,它增加了复杂度,也带来了额外的风险。

乐观锁实现方式:

  • 版本号(记为version):就是给数据增加一个版本标识,在数据库上就是表中增加一个version字段,每次更新把这个字段加1,读取数据的时候把version读出来,更新的时候比较version,如果还是开始读取的version就可以更新了,如果现在的version比老的version大,说明有其他事务更新了该数据,并增加了版本号,这时候得到一个无法更新的通知,用户自行根据这个通知来决定怎么处理,比如重新开始一遍。这里的关键是判断version和更新两个动作需要作为一个原子单元执行,否则在你判断可以更新以后正式更新之前有别的事务修改了version,这个时候你再去更新就可能会覆盖前一个事务做的更新,造成第二类丢失更新,所以你可以使用update … where … and version=”old version”这样的语句,根据返回结果是0还是非0来得到通知,如果是0说明更新没有成功,因为version被改了,如果返回非0说明更新成功。
  • 时间戳(timestamp):和版本号基本一样,只是通过时间戳来判断而已,注意时间戳要使用数据库服务器的时间戳不能是业务系统的时间。
  • 待更新字段:和版本号方式相似,只是不增加额外字段,直接使用有效数据字段做版本控制信息,因为有时候我们可能无法改变旧系统的数据库表结构。假设有个待更新字段叫count,先去读取这个count,更新的时候去比较数据库中count的值是不是我期望的值(即开始读的值),如果是就把我修改的count的值更新到该字段,否则更新失败。java的基本类型的原子类型对象如AtomicInteger就是这种思想。
  • 所有字段:和待更新字段类似,只是使用所有字段做版本控制信息,只有所有字段都没变化才会执行更新。

    乐观锁几种方式的区别:

    新系统设计可以使用version方式和timestamp方式,需要增加字段,应用范围是整条数据,不论那个字段修改都会更新version,也就是说两个事务更新同一条记录的两个不相关字段也是互斥的,不能同步进行。旧系统不能修改数据库表结构的时候使用数据字段作为版本控制信息,不需要新增字段,待更新字段方式只要其他事务修改的字段和当前事务修改的字段没有重叠就可以同步进行,并发性更高。

参考:https://blog.csdn.net/hemeinvyiqiluoben/article/details/80928070

获取事务隔离级别(isolation level)

DBCC USEROPTIONS

SQL Server 数据库隔离级别相关文章:

https://www.cnblogs.com/leohahah/p/8464575.html
https://www.cnblogs.com/chenmh/p/3998614.html

数据库事务与TransactionScope代码事务区别相关推荐

  1. 21 FI配置-财务会计-为非征税事务分配税务代码

    业务背景:为非征税事务分配税务代码 事务码: OBCL SPRO路径:SPRO->财务会计->财务会计全局设置->销售税/采购税->过账->为非征税事务分配税务代码 第1 ...

  2. java 数据库 事务 只读_不使用事务和使用只读事务的区别

    转转转,,还需要具体验证( 决定把readonly类型的事务完全去掉,以提高性能,这里有讨论:http://stackoverflow.com/questions/2562865/spring-tra ...

  3. mysql——数据库事务(C#代码)

    一.引言 MySQL事务主要用来处理数据量大.数据复杂度高的数据操作,最经典的使用场景是银行的转账:需要先从银行账户A中取出钱,然后再存入银行账户B中,如果中间出现问题,而没有事务的保证,那么就会出现 ...

  4. transactionscope mysql_TransactionScope事务对多个数据库的操作

    .Net 2.0引入了轻量级事务管理器(Lighweight Transaction Manager),即System.Transactions.TransactionManager. 轻量级事务管理 ...

  5. C#分布式事务(TransactionScope )

    TransactionScope是.Net Framework 2.0后,新增了一个名称空间.它的用途是为数据库访问提供了一个"轻量级"[区别于:SqlTransaction]的事 ...

  6. 数据库的四大特性和事务隔离级别

    数据库中经常被问到四大特性和隔离级别,一般都是涉及到概念性问题,在此做一些整理总结,方便理解. 1.事务的隔离级别 由低到高依次为Read uncommitted(未授权读取.读未提交).Read c ...

  7. 【数据库】第三章 事务、索引和SQL优化

    [数据库]第三章 事务.索引和SQL优化 文章目录 [数据库]第三章 事务.索引和SQL优化 一.事务 1.原子性 2.持久性 3.隔离性 4.一致性 二.索引 1.介绍 2.分类 3.底层实现 4. ...

  8. MSSQLSERVER数据库- 使用C#来操作事务[转]

    出处:http://www.cnblogs.com/cxeye/archive/2012/08/19/2646241.html 就在不久前,我在博客园看到一个名为英雄默问出处的博客.他里面有两篇是介绍 ...

  9. 深入理解Spring事务原理【为何有了数据库事务还要使用Spring事务】

    一.事务的基本原理 Spring事务 的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行:     ...

最新文章

  1. 腾讯年终奖刷屏了...
  2. scrapy-splash抓取动态数据例子六
  3. Linux 系统工具
  4. 区块链BaaS云服务(21)腾讯CCGP”跨链事务“
  5. 这些IT圈里的名词,你读对了吗
  6. 通过修改然后commit的方式创建自己的镜像
  7. leetcode406. 根据身高重建队列
  8. 前端学习(3230):React中的非受控组件
  9. github上成员贡献量_真祖传代码!你的GitHub代码已打包运往北极,传给1000年后人类...
  10. 解决tshark报错:tshark: Some fields aren‘t valid
  11. 代码好味道、坏味道与重构
  12. 从零开始创建react项目的三种方法(转)
  13. 使用插件扩展Docker
  14. java jsp 文件上传_JSP实现快速上传文件的方法
  15. 人大金仓数据库(kingbase7d)操作入门指南
  16. 你不知道的在线免费caj转Word
  17. dsp28335 Ecap总结
  18. make[1]: *** Waiting for unfinished jobs....
  19. 切比雪夫不等式例题讲解_「高中数学」柯西不等式,最全解析,高考必备,搞定最后十分...
  20. 氢os关闭android键盘,氢OS11到来前,先听听这些一加用户对氢OS的吐槽

热门文章

  1. 程序猿专属的国庆中秋放假通知!
  2. tracert与traceroute命令详解
  3. GUI 事件监听和文本框事件监听
  4. 虚拟机使用pc麦克风声卡
  5. 2022.3.21-3.27 AI行业周刊(第90期):中年裁员
  6. 画出烟熏眼妆的6大要点,清纯小女生谨记
  7. 中国小金属行业竞争现状与十四五运营形式分析报告2022版
  8. oracle中exists和not exists用法(包含经典例题:查看学了所有课程的同学的信息的通俗易懂解释)
  9. ExtractFileDrive、ExtractFilePath、ExtractFileDir
  10. 设置输入框和按钮对齐