事务相关(dljd-hiberate5)

一.什么是事务

理解1(dljd-wh-redis):事务是指一系列操作步骤(多条sql语句),这一系列的操作步骤,要么完全地执行(提交),要么完全地不执行(回滚)。

理解2:

1,定义:数据库事务访问(读)并可能更新(写)数据库中各种数据项的一个执行单元

2,组成:一个数据库事务通常包含对数据库进行的一个操作序列

3,目的:

                 为数据库提供了一个从失败中恢复到正常的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法

                 当多个应用程序在并发访问数据库时,可以这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

                总结~~~事务的目的就是要提供三种方法:

                        ①失败恢复方法

                        ②保持一致性的方法

                        ③操作隔离的方法

          4,三种情况下:

                成功情况下:能将数据从一种状态变为另一种状态,并能够持久化。
                异常情况下:①能将数据恢复到正常状态(解释:数据库中数据为 10,一个事务执行加一操作,操作结果为11,若提交时发生了异常,则应该回滚到初始状态10) ②要能保持一致性,包含数据的一致性和约束的一致性(解释:有学生表和选课表,学生01的成绩时90,学生02的成绩是80。数据一致性是指对学生01进行操作发生异常后进行回滚,回滚后不仅学生表中学生01的不变,其对应的选课表中学生01的成绩应该是90,保持不变。约束一致性是指若对学生表中新注册一个学生03,也要对应插入一条选课信息,若异常了,则要保证学生表和选课表都没有03的信息,若成功了,则应该都有,不能出现一个有一个没的情况 )
                并发情况下:并发的操作之间不能产生相互影响

理解3:

事务是数据库的逻辑工作单位。

事务(Transaction)是并发控制单位,是用户定义的一个操作序列,这些操作要么都做,要么都不做,是一个不可分割的工作单位。

一组对数据库的读写操作,必须具有以下四种特性(ACID:原子性、一致性、隔离性、持久性)的操作才能叫做事务。

事务通常以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。

理解4:

事务是恢复和并发控制的基本单位。

        事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

        事务通常由高级数据库操纵语言或编程语言(如SQLC++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。

        事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成(执行都执行,失败就回滚,对数据库数据没有影响)。

        例如:在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。或者例如银行转账工作:从一个账号扣款并在另一个账户增款,要么都执行,要么都不执行

理解5:Transaction 也就是所谓的事务了,通俗理解就是一件事情

二、为什么要使用事务?

我为什么要使用事务? 俺这里再举个很俗很俗的例子:

俺到银行存钱,于是有这么几个步骤:
1、把钱交给工作人员;2、工作人员填单;3、将单子给我签字;4、工作人员确认并输入电脑。

要是,要是我把钱交给工作人员之后,进行到3我签字了。那哥们突然心脏病发作,over掉了,那,我的钱还没有输入电脑,但我却交了钱又签字确认了,而并没有其他任何记录。我岂不是要亏死了???我的血汗钱啊!赶紧退给我!!

于是,在数据库里产生了这么一个术语:事务(Transaction),也就是要么成功,要么失败,并恢复原状。

还是写程序把:

 
  1. Create Proc sp我去存款(@M Money , @iOperator Int)

  2. As

  3. Begin

  4. Declare @i int

  5. Begin Tran --激活事务

  6. Exec @i=sp交钱 @m,@iOperator

  7. if @i<>0 --这里一般用系统错误号 @@Error。 我这里为了举例子没有用到。需要根据实际情况。

  8. begin

  9. Rollback Tran --回滚事务

  10. RaisError ('银行的窗口太少了,我懒得排队,不交了!:( ', 16, 1) with Log --记录日志

  11. Return -1 --返回错误号

  12. end

  13. Exec @i=sp填单 @m,@iOperator

  14. if @i<>0

  15. begin

  16. Rollback Tran --回滚事务

  17. RaisError ('银行的哥们打印机出了点毛病,打印不出单子来,把钱退回来给我吧??', 16, 1) with Log

  18. Return -2

  19. end

  20. Exec @i=sp签字 @m

  21. if @i<>0

  22. begin

  23. Rollback Tran --回滚事务

  24. RaisError ('我 靠?什么烂银行,换了3支笔都写不出水来!!老子不存了!!不签!', 16, 1) with Log

  25. Return -3

  26. end

  27. Exec @i=sp输入电脑 @m,@iOperator

  28. if @i<>0

  29. begin

  30. Rollback Tran --回滚事务

  31. RaisError ('什么意思?磁盘空间已满?好了好了,把钱给我,我到旁边的这家银行!', 16, 1) with Log

  32. Return -4

  33. end

  34. Commit Tran --提交事务

  35. Return 0

  36. End

三、事务四大特性(简称 ACID)

(1)原子性(Atomicity)
        事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执行。
(2)一致性(Consistency)
        几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致。
(3)隔离性(Isolation)
        事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
(4)持久性(Durability)
        对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现
故障。

四、事务的并发问题

      (以下内容引自由王珊、萨师煊主编,高等教育出版社出版的《数据库系统概念》第三章系统篇第11部分并发控制)
    多个事务对数据库的并发操作,可能会破坏事务的隔离性与一致性。由于并发访问而引发的这样的问题称为事务的并发问题。可能引发的并发问题主要包括三类:脏读、不可重复读和丢失修改。

1 脏读

        
        A 事务读取了 B 事务未提交的数据。
        说明:对于事务隔离级别设置较低的数据库,其是允许将未提交的数据写入到数据库的。
但是,即使写入到数据库,若事务回滚,也是可以再将数据恢复为原数据的。
        所以,可能发生脏读的现象:A 事务修改了某数据,但还未提交。此时,B 事务读取了
该数据。但此时 A 事务又发生了回滚。那么,B 事务读取到的就是个“不存在”的脏数据。

2 不可重复读

        读取了已提交的事务。事务A读取数据后,事务执行更新操作,使A无法再现前一次读取结果。不可重复读包括三种情况:
  1. 事务A读取某一数据后,事务B对其做了修改,当事务A再次读取数据时,得到与前一次不同的值。
  2. 事务A按一定条件从数据库中读取某数据记录后,事务B删除了其中部分记录,当A再次按相同条件读取数据时,发现某些记录神秘地消失了。
  3. 事务A按一定条件从数据库中读取某数据记录后,事务B插入了一些记录,当A再次按相同条件读取数据时,发现多了一些记录。
后两种不可重复读,也称为幻影现象。

3 丢失修改  -  写并发问题

        两个事务A与B,读入同一数据并修改,B提交的结果破坏了A提交的结果,导致A的修改丢失。

(1)第一类丢失更新
        也称为回滚丢失更新。A、B 事务同时读取某数据,并均做修改。A 事务先进行了提交,
而 B 事务又做回滚。此时,A 事务提交的更新数据丢失。
(2)第二类丢失更新
        也称为提交丢失更新。A、B 事务同时读取某数据,并均做修改。A 事务先做了提交,
154然后 B 事务也做提交。此时,A 事务提交的更新数据会被 B 事务的提交给覆盖。

4 幻读

        也称为虚读。这个问题并非是《数据库系统概论》中给出的并发问题。而是现实存在的,由于对数据库的并发访问所引发的问题。
        这里的幻读是指,在同一事务中,虽然多次执行相同的查询,查询结果是相同的。但后面的查询结果已经与DB中真正的数据不一致了。在同一事务中多次读取到的数据,不是真实的DB中当前数据,是虚的数据,是从缓存中读取的数据,就像是DB中数据的幻像。

四、事务的隔离级别

        产生上述三类数据不一致性的主要原因是并发操作破坏了事务的隔离性,并发控制就是要用正确的方式高度并发操作,使一个事务的执行不受其它事务的干扰,从而避免造成数据的不一致性。

         为了防止读并发问题的发生,标准 SQL 定义了四个隔离级别。级别由低到高分别为:读
取未提交、读取已提交、可重复读、串行化。随着隔离级别的提高,其防止并发的效果也是
逐步提高,但其系统开销也是逐步提高的,代码的执行效率是逐步降低的。
  1. 读取未提交:不防止任何并发问题
  2. 读取已提交:防止脏读,可能出现不可重复读与幻读
  3. 可重复读:防止脏读与不可重复读,可能出现幻读
  4. 串行化:不存在并发问题
        MySql 默认的事务隔离级别为可重复读 ,即防止了脏读与不可重复读,但可能会存在幻
读。通过 select @@global.tx_isolation;可以查询 MySql 默认的事务隔离级别。

         打开 JDK6 的帮助文档,查找到 java.sql.Connection 接口,其有五个常量,代表五个隔离级别。

 

这五个隔离级别分别代表的常量数字,可以从 JDK 帮助文档中查看到。

在这里插入图片描述

五、封锁机制

        事务的隔离级别,是DBMS隐式的为数据添加了锁。其底层实际上是在一个事务操作一个数据时,为该数据添加了一把锁。只有当该数据上的所有锁被释放掉后,其它事务才可操作该数据。但这个"操作"仅指修改、删除,不包括查询。当然,除了串行化级别是为表添加表级锁外,其它隔离级别所添加的锁均为行锁。
        在实际应用中,若要实现"只为某些满足条件的记录添加锁,其它数据处于正常事务隔离级别中"的情况,则可以为这些数据手工加锁。这个手工加锁,称为封锁。
        封锁是实现并发控制的一个非常重要的技术。所谓封锁是指,事务T在对某个数据对象例如表、记录等操作之前,先向系统发出请求,对其加锁。加锁后事务T就对该数据对象有了一定的控制,在事务T释放它的锁之前,其他的事务不能更新此数据对象。 

        锁可以分为两类:

        乐观锁:每次访问数据时,都会乐观的认为其它事务此时肯定不会同时修改该数据。在真正修改时,会在代码中通过对锁的状态的判断来判断数据是否被其它事务修改过,是在代码中完成的,所以乐观锁是加在代码中的。

        悲观锁:每次访问数据时,都会悲观的认为其它事务一定会同时修改该数据。所以,其在访问数据时,在数据库中就会给数据加锁,以防止其它事务同时修改该数据。所以锁是加在数据库中的。

1 乐观锁

         乐观锁是加在代码中的锁机制,一般充当乐观锁的有两类数据: 版本号与时间戳 。它们
的工作原理是相同的。
        A、B 事务从 DB 中读取数据时同时会读出一个数据版本号。当 A 事务将修改过的数据
写入到 DB 中时,会使版本号增 1。当 B 事务发生回滚或覆盖时,会首先对比自己数据的版
本号与 DB 中数据的版本号。若它们相等,则说明 DB 中数据没有发生变化,B 事务可以将
数据回滚到原始状态,或将修改写入到 DB 中。若小于 DB 中的版本号,则说明其它事务已
经修改过该数据,将抛出异常。

2 悲观锁

        悲观锁是加在DB中的封锁机制,又分为两种:排它锁,也称为X锁、写锁。共享锁,也称为S锁、读锁。

        悲观锁是行锁,若要为表中的记录添加行锁,则需要通过执行查询语句来为符合条件的记录添加指定的锁。

        在查询语句后添加for update,则会为每一条符合条件的记录添加写锁。例如:select * from student where id in(1,2,3) for update;会为id为1、2、3的记录添加写锁。

        此时其它事务可以修改id为1、2、3之外的其它记录数据,可以查看所有记录数据,但不能修改id为1、2、3的记录数据,不能再为这些数据添加其它类型的锁。

        在查询语句后添加lock in share mode,则会为每一条符合条件的记录添加读锁。例如:select * from student where id in(1,2,3) lock in share mode;id为1、2、3的记录添加读锁。

        此时其它事务可以再为这3条记录添加读锁,可以任意读取其中的数据,但就是不能修改这些数据,不能为该数据添加写锁。

排它锁:若事务T对数据对象A加上写锁,则只允许T读取和修改A,其他任何事务都不能再对A添加任何类型的锁。直到T释放A上的写锁。这就保证了其他事务在T释放A上的锁之前不能再修改A。

        但对于“表级锁”与“行级锁”,排它锁对于其它事务的读取权限规定是不同的。

        对于“表级锁”中的排它锁,其它事务不仅不能修改表中数据,连读取的权限也没有。即一旦为表添加了排它锁,则其它事务对该表的增删改查操作权限全无。

        对于“行级锁”中的排它锁,其它事务不能修改被锁定的数据,但可以读取。只不过读取到的是记录加锁之前DB中的原始数据。

共享锁:若事务T对数据对象A加上读锁,则事务T可以读取A但不能修改A,其他事务只能再对A加读锁,而不能加写锁,直到A上的读锁被全部释放。

排它锁与共享锁的区别总结:

  1. 一旦数据加上排它锁,则该数据上只能有排它锁这一把锁,不能再有其它任何锁。为该数据加锁的事务具有对该数据的增删改查的权限,而其它事务只有读取的权限。
  2. 一旦数据加上了共享锁,则该数据上可以添加很多共享锁,但不能添加排它锁。无论哪个事务,都只能读取数据,而不具有修改的权限。只有当该数据上的所有共享锁都被释放后,才可以为其添加排它锁。 

六、参考文献

(1)(Undo Log、Redo Log保证、事务隔离级别TNBLOG 事务简单理解 - 雨雨雨雨辰的专栏 - TNBLOG 事务简单理解 - 雨雨雨雨辰的专栏 - TNBLOG 

(2)csdn 事务的隔离级别(通俗易懂) 事务的隔离级别(通俗易懂)_孤刺-CSDN博客

(3)(从程序方面理解事务)csdn (16条消息) 通俗解释事务_CountryShi的博客-CSDN博客  https://blog.csdn.net/CountryShi/article/details/79280216

(4)csdn 数据库:事务(个人大白话详讲) 数据库:事务(个人大白话详讲)_hhhhxxn的博客-CSDN博客

(5)(双客户端演示一致性)大白话讲解事务的ACID_Mysql-IT乾坤技术博客

深入:

(1)简书 白话事务 白话事务 - 简书

(2)csdn 自我感觉最通俗易懂的事务到分布式事务的理解 自我感觉最通俗易懂的事务到分布式事务的理解_小样_lxl的博客-CSDN博客

(3)51CTO 面试官:你说对MySQL事务很熟?那我问你10个问题 - 51CTO.COM 面试官:你说对MySQL事务很熟?那我问你10个问题 - 51CTO.COM

(4)知乎 如何理解数据库事务中的一致性的概念? - 知乎 (zhihu.com) 如何理解数据库事务中的一致性的概念? - 知乎

(5)csdn (16条消息) 自我感觉最通俗易懂的事务到分布式事务的理解_小样_lxl的博客-CSDN博客 自我感觉最通俗易懂的事务到分布式事务的理解_小样_lxl的博客-CSDN博客

(6)csdn (16条消息) 数据库事务概念理解(通俗易懂)_hestyle的博客-CSDN博客 数据库事务概念理解(通俗易懂)_hestyle的博客-CSDN博客_数据库中事务的概念

(7)博客园 InnoDB核心特性-事务 - 六月OvO - 博客园 (cnblogs.com) InnoDB核心特性-事务 - 六月OvO - 博客园

(8)csdn (16条消息) 一文搞懂数据库隔离级别及解决方案_邓靖川的博客-CSDN博客 https://blog.csdn.net/weixin_43934104/article/details/105847463?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-5.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-5.base

(9)csdn (16条消息) 史上最清晰易懂的事务隔离级别图文讲解_西雅图的风的博客-CSDN博客 https://blog.csdn.net/ZYK1746914945/article/details/106885475?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-11.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-11.base

(10)csdn  通俗易懂的MySQL事务隔离 https://blog.csdn.net/qq_34161458/article/details/105059423

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值