2018-03-30 开胃学习.Net 系列 - Transaction 事务

Transactions

事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在计算机术语中,事务通常就是指数据库事务。

应用场景:
应用程序需要执行多个操作,包括一个或多个数据库命令

  • 其中一个数据库命令失败或某些其他操作失败(例如注册表更新)
  • 多项行动是为了一起工作。应用程序现在处于不一致的状态。
    我们使用 transaction 来解决这个问题,transaction 就是执行所需的一组命令原子操作
    ➢如果所有命令都成功完成,则 transaction 成功。
    ➢如果有任何命令失败,整个 transaction 将 rollback 到 pre-transaction 状态。
    ➢造成rollback的故障不一定与数据库相关。

ACID transaction properties 属性

All database management systems adhere to a set of properties known as the ACID properties:
并非任意的对数据库的操作序列都是数据库事务。数据库事务拥有以下四个特性,习惯上被称之为ACID特性

  • Atomicity: “All or nothing.” No partial success. Either the transaction succeeds in its entirety or it fails.
    原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

  • Consistency: Integrity constraints are met. Acceptable for inconsistency to occur during the transaction, but must be completely consistent upon completion.
    一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。

  • Isolation: The extent to which other transactions can “see” changes made by other transactions while they are executing.
    隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。

  • Durability: Guarantees permanent survival of data after the commit is complete.
    持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中

.NET 页、XML Web services方法或 .NET Framework 类一旦被标记为参与事务,它们将自动在事务范围内执行。您可以通过在页、XML Web services 方法或类中设置一个事务属性值来控制对象的事务行为。特性值反过来确定实例化对象的事务性行为。因此,根据声明特性值的不同,对象将自动参与现有事务或正在进行的事务,成为新事务的根或者根本不参与事务。声明事务属性的语法在 .NET Framework 类、.NET 页和 XML Web services 方法中稍有不同。
















Isolation Level 事务隔离层级

A property of the TransactionScope object, specifying the degree of transaction isolation.
隔离级别定义了事务与事务之间的隔离程度。
隔离级别与并发性是互为矛盾的:隔离程度越高,数据库的并发性越差;隔离程度越低,数据库的并发性越好。

  • Serializable (highest): read, write, and range locks (if necessary) used until end of the transaction.
    序列化:提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

  • RepeatableRead: Same, except no range locks. Other transactions can delete/update resulting in phantom reads.
    可重复读取:禁止不可重复读取和脏读取,但是有时可能出现幻读数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。

  • Snapshot: Instead of write-locking, “snapshot” of to-be-written data is taken and served to reading transactions.
    “snapshot” 取代 write-locking写锁定,获取待写入数据的 snapshot 并将其送达
    reading transactions。这个其实是tradeoff,并没有复制所有的数据,
    搞清楚OS中的 readlock,writelock, rangelock。
    读取数据时,可以保证读操作读取的行是事务开始时可用的最后提交版本。这意味着这种隔离级别可以保证读取的是已经提交过的数据,并且可以实现可重复读,也能确保不会幻读。

  • ReadCommitted: No dirty reads (not-yet-committed data from other transactions not visible), but non-repeatable reads may occur. (Default IL for SQL Server)
    授权读取:在commit之前,不允许dirty read(尚未提交的其他交易数据不可见)。但可能会发生不可重复的读取,因为反复读取会有不一样的结果。 (SQL Server的默认level)允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

  • ReadUncommitted (lowest): Dirty reads permitted. One transaction can see another transaction’s changes before the commit.
    未授权读取允许脏读,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。不管事务B何时Commit,事务A中的SELECT语句2都可以读出数据(有可能是脏数据,因事务B可能会ROLLBACK),且与语句1的数据不同。

Isolation Levels Illustrated



这个图按照时间顺序,上至下操作。

  1. UnCommitted level时,只要A做出了更改,B就会读取到这个更改,不存在Commit的考虑。

  2. Committed level时,T1读取了数据A,T2得到一样数据A。T1把数据修改为数据B,T2再读取依然是数据A。commit之后,T2 就会得到数据B。不可重复读。

  3. RepeatableRead和Serializable level时,区别在于Range Lock。T2 在commit之前,读取的都是未修改的数据A。

  4. 选择什么level很多程度上取决于我们对数据变化的重视程度。




下面是个例子:

















关于 三种 读

  1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

  2. 不可重复读 :是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两 次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不 可重复读。例如,一个编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果 只有在作者全部完成编写后编辑人员才可以读取文档,则可以避免该问题。

  3. 幻读 : 幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样.一般解决幻读的方法是增加范围锁RangeS,锁定检索范围为只读,这样就避免了幻读。

最高隔离级别SERIALIZABLE_READ可以保证不出现幻读的问题。
















Transactions in EF


在Entity Framework中使用 transaction 更容易:事务自动发生在同一个事务中上下文。

SaveChanges 就自动有了transaction,是readcommitted level。

  • Transactions using this technique are limited to the scope of the context in the using clause
  • Transactions spanning multiple contexts require heavier artillery: TransactionScope
    • You must add the reference System.Transactions
  • Connecting to multiple databases requires enabling MSDTC on the server.





在EF版本6中:

SaveChanges之后还要Commit。
Try block之后Catch,任何问题发生都可以rollback。




如果我们希望用其他level的isolation,则需要用TransactionScope object:
这里有 TransactionScope constructor。
需要两个参数,一个是new,一个是transaction option object 设置 isolation level,这里设置成最低的 Uncommitted。

下面的例子并未完成,因为没有rollback

















Change tracking

当修改EF对象或从容器中添加/删除EF对象时...

  • Changes are tracked locally by the context
  • You can stop change tracking by detaching an entity from the context. (example to follow)

Calling SaveChanges does the following:

  • Generates and executes SQL commands 生成并执行SQL命令
  • Commits changes to the database in a single transaction 在单个事务中提交对数据库的更改
  • Resets tracking information重置跟踪信息





改变跟踪 attaching/detaching 例子

c2 脱离了,改变不再被记录。Savechanges时,只有c1 会被记载,c2还是会被放在course的container里,在Course里还是可以看见c1和c2,但是数据库里只有c1。
















相关链接

彻底理解数据库事务
事务隔离层级(Transaction Isolation Level)
什么是脏读,不可重复读,幻读
百度 - 事务隔离级别
百度 - 幻读
Sql Server来龙去脉系列之三 查询过程跟踪

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容