MYSQL---复习准备

·数据库的概念
DB:数据库
DBMS:数据库管理系统MYSQL,Oracle,DB2,sqlserver
SQL:结构化语句查询
1.SQL语句的分类:
数据查询语句(DQL)—slect
数据操纵(DML)—insert,truncate(delete),update
数据定义语言(DDL)–create,drop,alter
事务语句(DCL)–grant,revoke

·MYSQL安装5.7.26-----结合PDF—文章末尾

  • window下启动mysql : 管理员身份进入cmd 进入cd D:\soft\mysql-5.7.26-winx64\bin net start/stop mysql
  • 退出exit
  • window 登陆 mysql -uroot -p 123456
  • Linux 登陆 mysql -h 远程主机号10.66.84.71 -u root -p 123456
  • 注意linux 登陆时候注意主机号!!!!!千万不要找错血一样的教训

在这里插入图片描述

1.入门指令:
2.常见函数

	a.字符函数:--------大小写控制函数
LOWER('SQL HAha')====>(sql haha)
UPPER('sql  HHHH')=====>(SQL HHHH)
					     --------字符控制函数
CONCAT('hello','world')===>helloworld 
SUBSTR('HelloWorld',1,5)>Hello
LENGTH('HelloWorld')====>10
INSTR('HelloWorld','W')===>6
LPAD(salary,10,'*')=======>****salary 
RPAD(salary,10,'*')=======>salary****
TRIM('H' from 'HelloWorld')=>elloWorld
REPLACE('abcd','b','m')====>amcd
b.数字函数

 - ROUND:四舍五入
 		ROUND(45.926,2)------>45.93
 - TRUNCATE:截断
 		TRUNC(45.926,2)------->45.92
 - MOD:求余
 		MOD(1600,300)---------->300
 - now():获取当前日期
c.条件表达式
IF-THEN-ELSE
case:查询部门号为10,20,30的员工信息,若部门号为10,则打印工资为其1.1倍数,20号部门,则打印工资为1.2倍,30号部门则打印工资为1.3倍
			select last_name,job_id,salary,
						CASE job_id WHEN 10 THEN 1.10*salary
											   WHEN 20 THEN 1.20*salary
											   	WHEN 30 THEN 1.30*salary
						ELSE salary END   "REVISED_SALARY"
										

3.子查询
概念:出现在其他语句内部的select语句,称为子查询,或者是内部查询

单行子查询
 - 1. 谁的工资比Abel高?
 	【SELECT  last_name FROM employees WHERE salary > all(SELECT salary FROM employee WHERE last_name = 'Abel'】
 - 2. 返回job_id与141员工号相同,salary比143号员工多的员工姓名,job_id 和 工资
 	【SELECT name,job_id,salary FROM employee WHERE job_id =141 AND salary >(select salary FROM employee WHERE department_id = 143) 】
 - 3. 返回工资最少员工的last_name,job_id和salary 
	【SELECT last_name,job_id,salary FROM employee WHERE salary = (SELECT MIN(salary) FROM employee 
 - 4. 查询最低工资大于40号部门最低工资的部门id和他的最低工资】
 	 【SELECT department_id,MIN(salary) FROM employee GROUP BY department_id HAVING MIN(salary) > (SELECT MIN(salary)  FROM employee WHERE department_id = 40】 AND department_id <> 40
多行子查询
IN/NOT IN------------------------------>列表中的任意一个
ANY | SOME--------------------------->和子查询返回的某一个值比较
ALL--------------------------------------->和子查询返回的所有数值比较

4.创建和管理表

  • 创建一个保存员工信息的数据库
    - create database employees;
    - show databases:查看当前所有的数据库
    - use employees:"使用"一个数据库
CREATE TABLE dept(
				#表示自增
				deptno INT(2) AUTO_INCREMENT,
				dname VARCHAR(14),
				loc CARCHAR(13),
				#主键
				PRIMARY KEY(deptno);
				)

数据类型:
INT:使用四个字节保存整数数据
CHAR:定长字符数据,若未指定,默认一个字符,最大长度255
VARCHAR:可变字符数据,根据字符串实际长度保存
FLOAT(M,D):M+D<6
DOUBLE(M,D):M+D<15
DATE:日期数据格式
BLOB:二进制的长文本数据
TEXT:长文本数据

  • 使用子查询创建表
复制现有的表:
		#复制数据
		CREATE TABLE emp1 AS  SELECT *FROM employee
		#复制表的结构
		CREATE TABLE emp1 AS  SELECT *FROM employee WHERE 1=2;
		#多表联查
		SELECT * FORM A,B,C,D where
		
  • 向已经有的表中添加,修改,删除,重命名现有表中的列
  • ALTER TABLE语句
追加一个新的列
		ALTER TABLE dept80
		ADD job_id VARCHAR(15);
可以修改列的数据类型,尺寸和默认值
		ALTER TABLE dept80
		MODIFY last_name VARCHAR(30);
	 MODIFY (salary double(9,2) default 1000);
  • 删除一个列
  • DROP COLUMN
ALTER TABLE dept80
DROP COLUMN job_id;
  • 重新命名一个列
  • CHANGE old_name new_name 数据类型
ALTER TABLE dept80
CHANGE department_name dept_name VARCHAR(15);
  • 删除一个表(数据和结构都删除)
DROP TABLE dept80;
  • 清空一个表(结构不删除)
  • TRUNCATE TABLE dept(不能够回滚)
  • DELETE语句可以回滚
truncate table dept;
delete from emp2;
select * from emp2;
rollback ;
select * from emp2;
  • 改变表,视图的名称
ALTER table dept 
RENAME TO detail_dept;

5.约束和分页
概念:

  • 为了保证数据的一致性和完整性,SQL规范以约束的方式对表数据进行额外 条件限制
  • 约束是表级的强制规定
  • 可以在创建表时规定约束,也可以在创建表以后进行约束,通过ALTER TABLE 语句

约束的种类:

  • NOT NULL非空约束
  • UNIQUE 唯一约束,规定某个字段在整个表中唯一
  • PRIMARY KEY 非空而且唯一
  • FOREIGN KEY 外键
  • CHECK 检查约束----(MYSQL不支持)
  • DEFAULT 默认值
NULL:(ALTER TABLE  MODIFY )
1.非空约束用于确保当前列的值不为空,非空约束只能够出现在表对象的列上
2.NULL类型特征值:
		>所有的类型值都可以是null,包括int,float
		>空字符串“ ”不等于NULL,0也不等于NULL;
UNIQUE:唯一约束允许出现多个空值:NULL
CREATE TABLE user (
		id INT NOT NULL,
		name VARCHAR(25),
		password VARCHAR(25),
		#使用表级约束语句法
		#表示name和password组合不能够重复
		CONSTRAINT uk_name_ped UNIQUE(name,password)
		);
		-添加唯一的约束
		ALTER TABLE USER
		ADD UNIQUE(name,password);
		ALTER TABLE USER
		ADD CONSTRAINT uk_name_ped UNIQUE(name,password);
		-删除约束
		ALTER TABLE user
		DROP INDEX uk_name_pwd
		
PRIMARY KEY ==唯一约束+非空约束
#列级模式
CREATE TABLE emp4(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20)
);
#表级模式
CREATE TABLE emp5(
id INT AUTO_INCREMENT ,
name VARCHAR(20),
pwd VARCHAR(15),
CONSTRAINT emp5_id_pk PRIMARY KEY(id)
);
#组合模式
CREATE TABLE emp5(
id INT AUTO_INCREMENT ,
name VARCHAR(20),
pwd VARCHAR(15),
CONSTRAINT emp7_pk PRIMARY KEY(name,pwd)
);
-增,删,改
ALTER TABLE sth
ADD/DROP /MODIFY

FOREIGN KEY(创建外键约束能够联表查询)
========================================
CREATE TABLE emp4(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20)
);
=======================================
CREATE TABLE dept(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20)
);
CONSTRAINT dept_emp5_id_fk FOREIGN KEY(id)
REFERENCE emp4(id)
======================================
-增,删除
		> ALTER TABLE emp
		   DROP FOREIGN KEY emp_dept_id_fk
		>ALTER  TABLE emp
		  ADD [CONSTRAINT emp_dept_id_fk] FOREIGN KEY(dept_id)  REFERENCE dept (dept_id);
======================================
		  -FOREIGN :指定子表中的列
		  -REFERENCE:标识父表中的列
		  -ON DELETE CASCADE(联级删除)当父亲删除时,子也应该删除
		  -ON DELETE SET NULL:子表中相应的列置空
		  FORENIGN KEY (class_name,classes_number)
		  REFERENCE class(name,number) ON DELETE CASCADE
  • List item

分页查询-limit:必须放在整个查询的最后面

前10条记录:select * from table limit 0,10
前11条至20条记录:select * from table limit 10,10
前21条至30条记录:select *from table limit 20,10;

6.事务

>1. 事务的概念和特性
  • 事务:事务由单独的单元的一个或者是多个SQL语句组成,在这个单元中,每个MYSQL语句是相互依赖的 而整个单独单元作为一个不可分隔的整体,如果单元中某条SQL语句一旦执行失败或者产生错误,真个单元将会回滚。所有受到影响的数据将返回事物开始以前的状态,如果单元中的所有SQL语句执行成功,则事务被顺利进行

    MySQL中存储引擎 [ 了解 ]

  • 概念:在mysql中的数据用各种不同的技术存储在文件(或内存)中

  • 通过show engines 查看

  • MySQL中常用的引擎有:innodb,myisam,memory等。其中innodb支持事务,mysiam和memory不支持

2.事务的ACID属性

  • 原子性
    事务是不可分隔的一个工作单位,事务操作中,要么都发生,要么都不发生
  • 一致性
    事务必须使数据库从一个状态转换成为另外一个状态
  • 隔离性
    事务的隔离性是指事务的执行不能够被其他事务干扰,也就是说一个事务内部的操作以及使用数据对并发其他事物是隔离的
  • 持久性
    持久性是指事务一旦被提交,他对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
    在这里插入图片描述

数据库提供四种事务的隔离级别:

  • -READ UNCOMMITTED:允许事务读取未被其他事务提交的变更和脏读,不可重复读和幻读都会出现

  • -READ COMMITED :只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可重复读和幻读问题仍然存

  • REPEATABLE READ:确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更改,避免了脏读和不可重复度读取,但是幻读仍然存

  • SERIALIZABLE(串行化):确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入,更新和删除,所有并发问题都解决,但是性能低下

  • Oracle支持两种:READ COMMITED(读取已经提交),SERIALIZABLE,默认事务隔离级别:READ COMMITED

  • Mysql支持4种,默认级别为:REPEATABL EREAD

  • 查看当前隔离级别:SELECT @@tx_isolation

  • 设置当前连接的隔离级别:set transation isolation level read committed

7.数据库范式

  • 第一范式(1NF):列不可分,eg:【联系人】(姓名,性别,电话),一个联系人有家庭电话和公司电话,那么这种表结构设计就没有达到 1NF

  • 第二范式(2NF):有主键,保证完全依赖。eg:订单明细表【OrderDetail】(OrderID,ProductID,UnitPrice,Discount,Quantity,ProductName),Discount(折扣),Quantity(数量)完全依赖(取决)于主键(OderID,ProductID),而 UnitPrice,ProductName 只依赖于 ProductID,不符合2NF;

  • 第三范式 (3NF):无传递依赖(非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况),eg:订单表【Order】(OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity)主键是(OrderID),CustomerName,CustomerAddr,CustomerCity 直接依赖的是 CustomerID(非主键列),而不是直接依赖于主键,它是通过传递才依赖于主键,所以不符合 3NF。

9.存储过程和函数的区别是什么

存储过程是用户定义的一系列SQL语句的集合,涉及特定的表或者其他对象的任务,用户可以调用存储过程。而函数通常是数据库已经定义的方法,它接收
参数,并且返回某种类型的值,并不涉及特定用户表

10.游标的作用,如何知道游标已经到达最后了呢??

游标用于定位结果集的行,通常判断全局变量@@FETCH_STATUS可以判断其是否到了最后,通常此变量不等于0表示出错或者到了最后

11.触发器分为事前触发和事后触发,这两种触发有何区别?语句级触发和行级触发有何区别?

触发器是与表相关的数据库对象,在满足定义条件时触发,并执行触发器中定义的语句集合。触发器的这种特性可以协助应用在数据库端确保数据库的完整性。
  事前触发运行于事前触发之前,事后触发运行于触发之后,语句级触发,可以运行在语句执行前或者执行之后,行级触发在触发器所影响的每一行触发一次

12.什么叫做SQL注入式攻击,如何防范?

所谓注入式攻击指的是,攻击者把SQL命令插入到Web表单的输入域或者页面请求的查询字符串中,欺骗服务器执行恶意的SQL命令,在某些表单中用户输入内容直接用来构造(或者影响)动态SQL命令,或者作为存储过程的输入参数,这类表单特别容易受到注入式攻击
防范SQL注入式攻击并不是一件特别困难的事情,只要在表单输入的内容构造SQL命令之前,把所有输入内容过滤一遍就够了,过滤输入内容可以按照多种方法进行。
-用来执行查询的数据库账号限制其权限 -将用户登陆的名字,密码等数据进行加密
-检查输入用户的合法性,确定输入内容只包含合法的数据

13.数据库索引
索引是对数据库表中一个或多个列的值进行排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B_TREE及其变种。索引加速了数据访问,因为存储引擎不会再去扫描整张表得到需要的数据;相反,它从根节点开始,根节点保存了子节点的指针,存储引擎会根据指针快速寻找数据。
14.索引有哪些结构
Hash索引和B+ Tree索引(5.7版本后InnoDB默认)

问:为什么采用B+ 树吗?这和Hash索引比较起来有什么优缺点吗?

答:因为Hash索引底层是哈希表,哈希表是一种以key-value存储数据的结构,所以多个数据在存储关系上是完全没有任何顺序关系的,所以,对于区间查询是无法直接通过索引查询的,就需要全表扫描。所以,哈希索引只适用于等值查询的场景。而B+ 树是一种多路平衡查询树,所以他的节点是天然有序的(左子节点小于父节点、父节点小于右子节点),所以对于范围查询的时候不需要做全表扫描

1、哈希索引适合等值查询,但是无法进行范围查询
2、哈希索引没办法利用索引完成排序
3、哈希索引不支持多列联合索引的最左匹配规则
4、如果有大量重复键值的情况下,哈希索引的效率会很低,因为存在哈希碰撞问题

15.问:文件和数据库为什么采用B+ 树,不采用红黑树?
 文件与数据库都是需要较大的存储,也就是说,它们都不可能全部存储在内存中,故需要存储到磁盘上。而所谓索引,则为了数据的快速定位与查找,那么索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数,因此B+树相比B树更为合适。数据库系统巧妙利用了局部性原理与磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入,而红黑树这种结构,高度明显要深的多,并且由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性。最重要的是,B+树还有一个最大的好处:方便扫库。B树必须用中序遍历的方法按序扫库,而B+树直接从叶子结点挨个扫一遍就完了,B+树支持range-query非常方便,而B树不支持,这是数据库选用B+树的最主要原因。
 
16.B树,B+树,红黑树,AVL树,的特点以及区别
(1). B-Tree(平衡多路查找树)
 B_TREE是一种平衡多路查找树,是一种动态查找效率很高的树形结构。B_TREE中所有结点的孩子结点的最大值称为B_TREE的阶,B_TREE的阶通常用m表示,简称为m叉树。一般来说,应该是m>=3。一颗m阶的B_TREE或是一颗空树,或者是满足下列条件的m叉树:

  • 树中每个结点最多有m个孩子结点;
  • 若根结点不是叶子节点,则根结点至少有2个孩子结点;
  • 除根结点外,其它结点至少有(m/2的上界)个孩子结点;
    B_TREE的查找类似二叉排序树的查找,所不同的是B-树每个结点上是多关键码的有序表,在到达某个结点时,先在有序表中查找,若找到,则查找成功;否则,到按照对应的指针信息指向的子树中去查找,当到达叶子结点时,则说明树中没有对应的关键码。由于B_TREE的高检索效率,B-树主要应用在文件系统和数据库中,对于存储在硬盘上的大型数据库文件,可以极大程度减少访问硬盘次数,大幅度提高数据检索效率

2)B+Tree : InnoDB存储引擎的索引实现
  B+Tree是应文件系统所需而产生的一种B_TREE树的变形树。一棵m阶的B+树和m阶的B_TREE的差异在于以下三点:

  • n 棵子树的结点中含有n个关键码;
  • 所有的叶子结点中包含了全部关键码的信息,及指向含有这些关键码记录的指针,且叶子结点本身依关键码的大小自小而大的顺序链接;
  • 非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键码。
      通常在B+树上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点。因此可以对B+树进行两种查找运算:一种是从最小关键字起顺序查找,另一种是从根节点开始,进行随机查找。
      在B+树上进行随机查找、插入和删除的过程基本上与B-树类似。只是在查找时,若非终端结点上的关键码等于给定值,并不终止,而是继续向下直到叶子结点。因此,对于B+树,不管查找成功与否,每次查找都是走了一条从根到叶子结点的路径

(3). 为什么说B±tree比B 树更适合实际应用中操作系统的文件索引和数据库索引?

  • B+tree的磁盘读写代价更低:B+tree的内部结点并没有指向关键字具体信息的指针(红色部分),因此其内部结点相对B
    树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多,相对来说IO读写次数也就降低了;
  • B+tree的查询效率更加稳定:由于内部结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引,所以,任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当;
  • 数据库索引采用B+树而不是B树的主要原因:B+树只要遍历叶子节点就可以实现整棵树的遍历,而且在数据库中基于范围的查询是非常频繁的,而B树只能中序遍历所有节点,效率太低。

18.索引的优点

  • 大大加快数据的检索速度,这也是创建索引的最主要的原因;
  • 加速表和表之间的连接;
  • 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间;
  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性

19.什么情况下设置了索但是无法使用

  • 以“%(表示任意0个或多个字符)”开头的LIKE语句,模糊匹配;
  • OR语句前后没有同时使用索引;
  • 数据类型出现隐式转化(如varchar不加单引号的话可能会自动转换为int型);
  • 对于多列索引,必须满足 最左匹配原则 (eg:多列索引col1、col2和col3,则 索引生效的情形包括 col1或col1,col2或col1,col2,col3)。

20.什么样的字段适合创建索引?

  • 经常作查询选择的字段
  • 经常作表连接的字段
  • 经常出现在order by, group by, distinct 后面的字段

21.索引有哪些索引

  • 主键索引(聚集索引)
  • 普通索引
  • 唯一索引
  • 全文索引
    聚集索引和非聚集索引的区别

聚集索引的顺序就是数据的物理存储顺序,而非聚集索引的解释是索引顺序与物理存储数据无关,正因为如此一个表中最多一个聚集索引
SQLserver中索引是用二叉树的数据结构描述的,我们可以这样理解聚集索引,索引的叶节点就是数据节点,而非聚集索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据

22. 索引的缺点

  • 时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度;
  • 空间方面:索引需要占物理空间

23.主键、自增主键、主键索引与唯一索引概念区别
主键:指字段 唯一、不为空值 的列;

主键索引:指的就是主键,主键是索引的一种,是唯一索引的特殊类型。创建主键的时候,数据库默认会为主键创建一个唯一索引;

自增主键:字段类型为数字、自增、并且是主键;

唯一索引:索引列的值必须唯一,但允许有空值。主键是唯一索引,这样说没错;但反过来说,唯一索引也是主键就错误了,因为唯一索引允许空值,主键不允许有空值,所以不能说唯一索引也是主键。

24.主键就是聚集索引吗?主键和索引有什么区别?
  主键是一种特殊的唯一性索引,其可以是聚集索引,也可以是非聚集索引。在SQLServer中,主键的创建必须依赖于索引,默认创建的是聚集索引,但也可以显式指定为非聚集索引。InnoDB作为MySQL存储引擎时,默认按照主键进行聚集,如果没有定义主键,InnoDB会试着使用唯一的非空索引来代替。如果没有这种索引,InnoDB就会定义隐藏的主键然后在上面进行聚集。所以,对于聚集索引来说,你创建主键的时候,自动就创建了主键的聚集索引

25.实践中如何优化数据库
   实践中,MySQL的优化主要涉及SQL语句及索引的优化、数据表结构的优化、系统配置的优化和硬件的优化四个方面,如下图所示:
   在这里插入图片描述
  
26.简单说一说drop、delete与truncate的区别
SQL中的drop、delete、truncate都表示删除,但是三者有一些差别:

  • Delete用来删除表的全部或者一部分数据行,执行delete之后,用户需要提交(commmit)或者回滚(rollback)来执行删除或者撤销删除, delete命令会触发这个表上所有的delete触发器;
  • Truncate删除表中的所有数据,这个操作不能回滚,也不会触发这个表上的触发器,TRUNCATE比delete更快,占用的空间更小;
  • Drop命令从数据库中删除表,所有的数据行,索引和权限也会被删除,所有的DML触发器也不会被触发,这个命令也不能回滚。

因此,在不再需要一张表的时候,用drop;在想删除部分数据行时候,用delete;在保留表而删除所有数据的时候用truncate。

27、MySQL中的悲观锁与乐观锁的实现
悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念。

(1). 悲观锁
  悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的认为所有的操作均会导致并发安全问题,因此要先确保获取锁成功再进行业务操作。通常来讲,在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select … for update时会获取被select中的数据行的行锁,因此其他并发执行的select … for update如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。
  这里需要特别注意的是,不同的数据库对select… for update的实现和支持都是有所区别的,例如oracle支持select for update no wait,表示如果拿不到锁立刻报错,而不是等待,mysql就没有no wait这个选项。另外,mysql还有个问题是: select… for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此,如果在mysql中用悲观锁务必要确定使用了索引,而不是全表扫描。

(2). 乐观锁
  乐观锁的特点先进行业务操作,只在最后实际更新数据时进行检查数据是否被更新过,若未被更新过,则更新成功;否则,失败重试。乐观锁在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持。一般的做法是在需要锁的数据上增加一个版本号或者时间戳,然后按照如下方式实现:

1. SELECT data AS old_data, version AS old_version FROM …;
2. 根据获取的数据进行业务操作,得到new_data和new_version
3. UPDATE SET data = new_data, version = new_version WHERE version = old_version
if (updated row > 0) {
    // 乐观锁获取成功,操作完成
} else {
    // 乐观锁获取失败,回滚并重试
}

乐观锁是否在事务中其实都是无所谓的,其底层机制是这样:在数据库内部update同一行的时候是不允许并发的,即数据库每次执行一条update语句时会获取被update行的写锁,直到这一行被成功更新后才释放。因此在业务操作进行前获取需要锁的数据的当前版本号,然后实际更新数据时再次对比版本号确认与之前获取的相同,并更新版本号,即可确认这其间没有发生并发的修改。如果更新失败,即可认为老版本的数据已经被并发修改掉而不存在了,此时认为获取锁失败,需要回滚整个业务操作并可根据需要重试整个过程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章