JAVA WEB DAY 10_ MySQL 多表查询 与 事物

MySQL多表查询与事务

目标

  • 能够说出多表之间的关系及其建表原则
  • 能够理解三大范式
  • 能够使用内连接进行多表查询
  • 能够使用左外连接和右外连接进行多表查询
  • 能够使用子查询进行多表查询
  • 能够理解多表查询的规律
  • 能够理解事务的概念
  • 能够说出事务的原理
  • 能够在MySQL中使用事务

01_DCL-[★]

  • 创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码'

关键字说明:
​ 1. 用户名:将创建的用户名
​ 2. 主机名:指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost,如果想让该用户可以从任意远程主机登陆,可以使用通配符%
​ 3. 密码:该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器

具体操作

-- user1用户只能在localhost这个IP登录mysql服务器
CREATE USER 'user1'@'localhost' IDENTIFIED BY '123';
-- user2用户可以在任何电脑上登录mysql服务器
CREATE USER 'user2'@'%' IDENTIFIED BY '123';
  • 授权用户

用户创建之后,基本没什么权限!需要给用户授权

GRANT 权限1, 权限2... ON 数据库名.表名 TO '用户名'@'主机名';

关键字说明
​ 1. GRANT 授权关键字
​ 2. 授予用户的权限,如SELECTINSERTUPDATE等。如果要授予所的权限则使用ALL
​ 3. 数据库名.表名:该用户可以操作哪个数据库的哪些表。如果要授予该用户对所有数据库和表的相应操作权限则可用*表示:比如 *.*

​ 4. '用户名'@'主机名': 给哪个用户授权

具体操作:

  1. 给user1用户分配对test这个数据库操作的权限
GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON day10.* TO 'user1'@'localhost';
  1. 给user2用户分配对所有数据库操作的权限
GRANT ALL ON *.* TO 'user2'@'%';
  • 撤销授权
REVOKE  权限1, 权限2... ON 数据库.表名 FROM '用户名'@'主机名';

具体操作:

-- 撤销user1用户对test操作的权限
REVOKE DELETE ON day10.* FROM 'user1'@'localhost';
  • 查看权限
SHOW GRANTS FOR '用户名'@'主机名';

具体操作:

-- 查看user1用户的权限
SHOW GRANTS FOR 'user1'@'localhost';
  • 删除用户
DROP USER '用户名'@'主机名';

具体操作:

-- 删除user2
DROP USER 'user2'@'%';
  • 修改用户密码
-- 修改管理员密码
mysqladmin -uroot -p password 新密码  -- 新密码不需要加上引号
-- 注意:需要在未登陆MySQL的情况下操作。

具体操作:

mysqladmin -uroot -p password 123456
输入老密码
  • 修改普通用户密码
set password for '用户名'@'主机名' = password('新密码');
-- 注意:需要在登陆MySQL的情况下操作。

具体操作:

set password for 'user1'@'localhost' = password('新密码'); -- windows 系统

02_数据库备份和还原-[★★★]

  • source命令备份与还原

备份格式
mysqldump -u用户名 -p密码 数据库 > 文件的路径

还原格式
SOURCE 导入文件的路径;

注意:还原的时候需要先登录MySQL,并选中对应的数据库

03_数据库三大范式-[★★]

  • 三大范式
数据库三大范式小结说明
1NF最基本的要求,每一列必须具有原子性,不可再分割
2NF满足1NF基础上,满足下面两个条件
每张表必须有主键
一张表只描述一件事件
3NF满足2NF基础上,满足一个条件
一张表只能引用另一张表的主键列的值。
  • 第一范式

第一范式:最基本的要求,每一列要保证原子性,不可再分割

总结:如果不遵守第一范式,查询出数据还需要进一步处理(查询不方便)。遵守第一范式,需要什么字段的数据就查询什么数据(方便查询)。

  • 第二范式

第二范式(2NF):要求在第一范式的基础上数据库表中的每个实例或记录必须可以被唯一地区分,表中的每一个字段都依赖于主键。
第二范式:在满足第一范式的基础上,再满足如下两个条件:

  1. 一张表只能描述一件事情
  2. 每张表必须有主键

总结:如果不准守第二范式,数据冗余,相同数据无法区分。遵守第二范式减少数据冗余,通过主键区分相同数据。

  • 第三范式

第三范式(3NF):是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。
第三范式:满足第二范式之后要求一张表中不能引用另一张表的非主键字段的值。

总结:如果不准守第三范式,可能会有相同数据无法区分,修改数据的时候多张表都需要修改(不方便修改)。遵守第三范式通过id可以区分相同数据,修改数据的时候只需要修改一张表(方便修改)。

04_表关系-一对一-[★★★]

一对一表关系建表原则小结说明
外键唯一主表的主键和从表的外键(唯一),形成主外键关系,外键唯一
外键是主键主表的主键和从表的主键,形成主外键关系
  • 示例代码
-- 表关系-一对一关系建表 
-- 创建简历表
create table jl(
	id int primary key auto_increment,
	content varchar(2000)
);
-- 创建学生表
create table stu(
	id int primary key auto_increment,
	name varchar(20) not null,
	jl_id int  unique,  -- 唯一约束 
	constraint foreign key(jl_id) references jl(id) -- 外键约束
);
-- 设计原则二
drop table stu;
drop table jl;
-- 创建简历表
create table jl(
	id int primary key auto_increment,
	content varchar(2000)
);
-- 创建学生表
create table stu(
	id int primary key auto_increment,
	name varchar(20) not null,
	constraint foreign key(id) references jl(id) -- 外键约束
);

05_表关系-一对多-[★★★]

一对多建表原则小结
在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
  • 示例代码
-- 创建员工表
create table employee(
	id int primary key auto_increment,
	name varchar(20) not null,
	age int,
	dept_id int  -- 部门编号
);
-- 创建从表 employee 并添加外键约束
create table employee(
	id int primary key auto_increment,
	name varchar(20) not null,
	age int,
	dept_id int, -- 部门编号
	constraint  foreign key(dept_id) references dept(id) -- 添加外键约束
);

06_表关系-多对多-[★★★]

多对多建表原则小结
需要创建一个中间表,中间表至少有两个字段,这两个字段分别作为外键引用各种1方的主键,这两个字段一起作为中间表主键共同确定中间表记录的唯一性,主键称为联合主键。
  • 示例代码
-- 学生表
create table student(
	id int primary key auto_increment,
	name varchar(20) not null
);
-- 课程表
create table course(
	id int primary key auto_increment,
	name varchar(20) not null
);
-- 中间表
create table student_course(
	sid int, -- 学号
	cid int, -- 课程号
	constraint foreign key(sid) references student(id),
	constraint foreign key(cid) references course(id), 
	primary key(sid,cid) -- 联合主键
);

08_多表查询概述和数据准备-[★★]

  1. 什么是多表查询:从多张中查询数据的过程
  2. 多表查询的使用场景:当需要显示的数据来自于多张表时就要使用到多表连接查询
  3. 多表查询的方式
    交叉查询:笛卡尔积的结果
    内连接查询(使用最多)
      隐式内连接查询
      显式内连接查询
    外连接查询
      左外连接查询
      右外连接查询
    全连接查询:MySQL不支持
  • 多表查询数据准备
drop table employee;
drop table dept;
# 多表查询数据准备
-- 创建部门表(部门编号,部门名称)
create table dept(
	id int primary key auto_increment,
	name varchar(20) not null
);
-- 插入三个部门:开发部,市场部,财务部
insert into dept(name) values('开发部'),('市场部'),('财务部');

-- 创建员工表(员工编号,员工姓名,性别,工资,入职日期,部门编号)
create table emp(
	id int primary key auto_increment,
	name varchar(20) not null,
	gender char(1),
	salary double,
	join_date date,
	dept_id int,
	constraint foreign key(dept_id) references dept(id)
);
-- 插入员工数据
insert into emp(name,gender,salary,join_date,dept_id) values('孙悟空','男',7200,'2013-02-24',1);
insert into emp(name,gender,salary,join_date,dept_id) values('猪八戒','男',3600,'2010-12-02',2);
insert into emp(name,gender,salary,join_date,dept_id) values('唐僧','男',9000,'2008-08-08',2);
insert into emp(name,gender,salary,join_date,dept_id) values('白骨精','女',5000,'2015-10-07',3);
insert into emp(name,gender,salary,join_date,dept_id) values('蜘蛛精','女',4500,'2011-03-14',1);

select * from dept;
select * from emp;

09_笛卡尔积现象-[★★]

  1. 什么是笛卡尔积:查询记录数等于多张表记录数之积。
  2. 如何清除笛卡尔积现象:在查询时加上过滤条件:从表.外键列名=主表.主键
内连接查询分类语法
隐式内连接select * from 左表,右表 where 条件;
显示内连接select * from 左表 inner join 右表 on 条件; <br />inner 关键字可以省略

内连接查询的特点: 使用左表的记录去匹配右表的记录,只有满足条件的记录才会查询出来。

总结多表连接查询步骤:

  1. 先确定要查询的表有哪些
  2. 然后确定要查询的字段有哪些
  3. 最后确定查询条件
  • 示例演示:笛卡尔积现象
# 查询员工信息(包括部门信息)
select * from emp , dept ;
  • 示例演示:清除笛卡尔积现象
# 查询员工信息(包括部门信息) 消除笛卡尔积
select * from emp e, dept  d where  dept_id = d.id ;

10_内连接查询-[★★★]

  • 示例演示:内连接查询
# 分别使用隐式内连接和显示内连接查询
-- 查询唐僧的信息,显示员工id,姓名,性别,工资和所在的部门名称。
-- 隐式内连接查询
select emp.id 员工编号, emp.name 姓名, gender 性别, salary 工资, dept.name 部门名称
from emp,dept where dept_id = dept.id and emp.name = '唐僧';
-- 显式内连接查询:inner join 表名 on 条件
/*
1. 先确定要查询的表有哪些
2. 然后确定要查询的字段有哪些
3. 最后确定查询条件
*/
select e.id, e.name, e.`gender`, e.`salary`, d.`name`  -- 要查询的字段
from emp e          -- 要查询的表
inner join dept d  -- 要连接的表
on  e.`dept_id` = d.`id`  and  e.`name` = '唐僧'; -- 查询条件

11_左外连接查询-[★★★]

左外连接查询小结
语法:select 字段 from 左表 left join 右表 on 条件;
特点:能够保证左表的记录全部查询出来。
  • 数据准备
-- 左连接查询
-- 语法:left  join 表名 on 条件
-- 特点:能够保证左表的记录全部查询出来。
# 在部门表中增加一个销售部
insert into dept(name) values('销售部');
# 使用内连接查询员工信息和部门信息
select e.*,d.* 				-- 要查询的字段
from dept d    	        -- 要查询的表
inner join   emp e              -- 要连接的表
on e.`dept_id` = d.`id`;   -- 连接条件
  • 示例演示:左连接查询
-- 左连接查询
-- 语法:left  join 表名 on 条件
-- 特点:能够保证左表的记录全部查询出来。
# 在部门表中增加一个销售部
insert into dept(name) values('销售部');
# 使用左连接查询员工信息和部门信息
select e.*,d.* 				-- 要查询的字段
from dept d    	        -- 要查询的表
left join   emp e              -- 要连接的表
on e.`dept_id` = d.`id`;   -- 连接条件

12_右外连接查询-[★★★]

右外连接查询小结
语法:select 字段 from 左表 right join 右表 on 条件;
特点:能够保证右表的记录全部查询出来
  • 示例演示:右外连接查询
# 在员工表中增加一个员工,该员工没有部门
insert into emp values(null,'沙僧','男',1800,'2010-02-20',null);
-- 右连接的语法:right join 表 on 条件
-- 右连接的特点:能够保证右表的记录全部查询出来
# 使用右连接查询员工信息和部门信息
select  e.*,d.* 			-- 要查询的字段
from dept d		-- 要查询的表
right join emp e     -- 要连接的表
on d.`id` = e.`dept_id`;   -- 连接条件

select  e.*,d.* 			-- 要查询的字段
from emp e		-- 要查询的表
left join dept d     -- 要连接的表
on d.`id` = e.`dept_id`;   -- 连接条件

13_子查询概述-[★★]

子查询概述说明
什么是子查询一条查询语句中嵌套了另一条查询语句
里面的查询语句称为子查询语句
外面的查询语句称为父查询语句
子查询分类单行单列子查询
多行单列子查询
多行多列子查询
子查询应用场景当一条查询语句使用到的数据需要通过另一条查询语句获取时

14_单行单列子查询-[掌握]

单行单列子查询概念:子查询的结果是单行单列的值,父查询可以使用比较运算符

  • 示例演示
# 查询工资最高的员工是谁
-- 先查询最高工资是多少
select max(salary) from emp;
-- 查询工资最高的员工是谁
select * from emp where salary = (select max(salary) from emp);

# 查询工资小于平均工资的员工有哪些
-- 先查询平均工资是多少
select avg(salary) from emp;
-- 然后查询工资小于平均工资的员工信息
select * from emp where salary < (select avg(salary) from emp);

# 查询工资大于"蜘蛛精"的员工
-- 先查询蜘蛛精的员工工资
select salary from emp where name ='蜘蛛精';
-- 然后查询工资大于蜘蛛精的员工信息
select * from emp where salary > (select salary from emp where name ='蜘蛛精');

15-多行单列子查询-[★★★]

多行单列子查询概述:子查询结果是多行单列的值,父查询使用in关键字

  • 示例演示
-- 多行单列子查询:子查询结果是多行单列的值
# 查询工资大于5000的员工,来自于哪些部门的名字  
-- 查询工资大于5000的员工的部门id
select dept_id from emp where salary > 5000;
-- 根据部门id查询部门名称
select id, name from dept where id = 1 || id = 2;
select id, name from dept where id in (select dept_id from emp where salary > 5000);

# 查询开发部与财务部所有的员工信息
-- 先查询部门表获取到开发部与财务部的id
select id from dept where name in ('开发部','财务部');
-- 根据部门id查询部门员工信息
select * from emp where dept_id in (select id from dept where name in ('开发部','财务部'));

16-多行多列子查询-[★★★]

多行多列子查询概述:子查询的结果是多行多列的值,可以将子查询的结果当成一张虚拟表使用,可以和其他表进行表连接查询。

  • 示例代码
# 多行多列子查询
-- 查询2011年以后入职的员工信息和部门信息。
-- 先查询员工表:查询2011年以后入职的员工信息
select * from emp where join_date > '2010-12-31';
select e.*,d.*  
from dept d     -- 要查询的表(真实存在的表)
inner join  (select * from emp where join_date > '2010-12-31')  e    -- 要连接的表(虚拟表)
on   e.dept_id = d.id; -- 连接条件

17_多表查询案例-[★★★]

多表连接查询步骤

  1. 先确定要查询的表有哪些
  2. 然后确定要查询的字段有哪些
  3. 最后确定连接条件

连接条件数量:至少=表的数量 - 1 如果表之间有主外键关联则必须将主外键等号连接作为查询条件。

连接条件:从表.外键列名 = 主表.主键列名;

  • 准备数据
-- 部门表
CREATE TABLE dept (
  id INT PRIMARY KEY PRIMARY KEY, -- 部门id
  dname VARCHAR(50), -- 部门名称
  loc VARCHAR(50) -- 部门位置
);

-- 添加4个部门
INSERT INTO dept(id,dname,loc) VALUES 
(10,'教研部','北京'),
(20,'学工部','上海'),
(30,'销售部','广州'),
(40,'财务部','深圳');

-- 职务表,职务名称,职务描述
CREATE TABLE job (
  id INT PRIMARY KEY,
  jname VARCHAR(20),
  description VARCHAR(50)
);

-- 添加4个职务
INSERT INTO job (id, jname, description) VALUES
(1, '董事长', '管理整个公司,接单'),
(2, '经理', '管理部门员工'),
(3, '销售员', '向客人推销产品'),
(4, '文员', '使用办公软件');

-- 员工表
CREATE TABLE emp (
  id INT PRIMARY KEY, -- 员工id
  ename VARCHAR(50), -- 员工姓名
  job_id INT, -- 职务id
  mgr INT , -- 上级领导
  joindate DATE, -- 入职日期
  salary DECIMAL(7,2), -- 工资
  bonus DECIMAL(7,2), -- 奖金
  dept_id INT, -- 所在部门编号
  CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
  CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
);

-- 添加员工
INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);

-- 工资等级表
CREATE TABLE salarygrade (
  grade INT PRIMARY KEY,
  losalary INT,
  hisalary INT
);

-- 添加5个工资等级
INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 
(1,7000,12000),
(2,12010,14000),
(3,14010,20000),
(4,20010,30000),
(5,30010,99990);
  • 查询需求
# 查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述
select  e.id 员工编号, e.ename 员工姓名, e.salary 工资,
  j.jname 职务名称, j.`description` 职务描述    -- 要查询的字段
from emp e -- 要查询的表
inner join job j -- 要连接的表
on  j.id = e.`job_id` -- 连接条件 
order by e.id; 
# 查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
select  e.id 员工编号, e.ename 员工姓名, e.salary 工资,
  j.jname 职务名称, j.`description` 职务描述, d.`dname` 部门名称, d.loc 部门位置    -- 要查询的字段
from emp e -- 要查询的表
inner join job j -- 要连接的表
inner join dept  d -- 要连接的表
on e.`dept_id` = d.`id` and j.id = e.`job_id`; -- 连接条件
# 查询所有员工信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
select  e.ename 员工姓名, e.salary 工资,   -- 要查询的字段
  j.jname 职务名称, j.`description` 职务描述, 
  d.`dname` 部门名称, d.loc 部门位置, s.`grade`  工资等级
from emp e -- 要查询的表
inner join job j -- 要连接的表
inner join dept  d -- 要连接的表
inner join salarygrade s -- 要连接的表
on e.`dept_id` = d.`id` -- 连接条件
and j.id = e.`job_id`
and e.salary between s.`losalary` and  s.`hisalary`;   -- (100,200]
# 查询经理的信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
select  e.ename 员工姓名, e.salary 工资,   -- 要查询的字段
  j.jname 职务名称, j.`description` 职务描述, 
  d.`dname` 部门名称, d.loc 部门位置, s.`grade`  工资等级
from emp e -- 要查询的表
inner join job j -- 要连接的表
inner join dept  d -- 要连接的表
inner join salarygrade s -- 要连接的表
on e.`dept_id` = d.`id` -- 连接条件
and j.id = e.`job_id`
and e.salary between s.`losalary` and  s.`hisalary`
and j.`jname` = '经理';  
# 查询出部门编号、部门名称、部门位置、部门人数
-- ifnull(字段名,默认值)   当指定字段的值为null时使用默认值代替
select   d.id 部门编号,d.`dname` 部门名称  -- 查询的字段
, d.`loc` 部门位置, ifnull(e.total,0) 部门人数
from dept d   -- 要查询的表
left join (select dept_id , count(*) total from emp group by dept_id) e  -- 要连接的表
on d.id = e.dept_id; -- 连接条件

18_事务概述-[★★]

在实际的业务开发中,有些业务操作要多次访问数据库。一个业务要发送多条SQL语句给数据库执行。需要将多次访问数据库的操作视为一个整体来执行,要么所有的SQL语句全部执行成功。如果其中有一条SQL语句失败,就进行事务的回滚,所有的SQL语句全部执行失败。

事务:将一个业务操作中的多条SQL语句当成一个整体对待,这多条SQL语句要么全部执行成功,要么全部执行失败,如果有一条SQL语句执行失败,则会撤销已经成功执行的SQL语句。

  • 例如:jack给rose转账,jack账号减钱,rose账号加钱
-- 创建账户表
create table account(
	id int primary key auto_increment,
	username varchar(20) not null,
	balance double
);
-- 添加账户数据
insert into account(username,balance) values('jack',1000),('rose',1000);

select * from account;
  • 模拟jack给rose转500元钱,一个转账的业务操作最少要执行下面的2条语句:
  1. jack账号-500
  2. rose账号+500
-- 1. jack账号-500
update account set balance = balance - 500 where id = 1;

-- 2. rose账号+500
update account set balance = balance + 500 where id = 2;
select * from account;

假设当jack账号上-500元,服务器崩溃了。rose的账号并没有+500元,数据就出现问题了。我们需要保证其中一条SQL语句出现问题,整个转账就算失败。只有两条SQL都成功了转账才算成功。这个时候就需要用到事务

19_事务管理-手动提交事务-[★★★]

手动管理事务小结语句
开启事务start transaction;
提交事务commit;
回滚事务rollback;

总结:
如果事务中SQL语句没有问题,commit提交事务,会对数据库数据的数据进行改变。
如果事务中SQL语句有问题,rollback回滚事务,会回退到开启事务时的状态。

20_事务管理-自动提交事务-[★★★]

  1. MySQL事务的默认管理方式:
    MySQL的每一条SQL语句都是一个单独的事务,每条语句都会自动开启一个事务,执行完毕自动提交事务,MySQL默认开始自动提交事务
  2. 如何禁止自动提交事务:set autocommit=0;

21_事务原理-[★★]

  1. 当执行start transaction开启事务后,内部会准备一个临时的日志文件。
  2. 接下来执行的所有SQL语句的结果会先保存到日志文件中
  3. 当执行commit语句,才会将日志文件中的内容同步到数据库中并清空日志文件的内容
  4. 当执行rollback语句,则会直接清空日志文件的内容,并不会被同步到数据库中。

22_回滚点-[★]

回滚点的作用:可以让我们在失败的时候回到指定位置(回滚点),而不是回到事务开启的时候。
设置回滚点的语法:savepoint 名字;
回到回滚点的语法:rollback to 名字;

23-事务的四大特性-[面试题]

事务四大特性说明
A:atomic 原子性事务中的多条SQL语句是一个整体,不可再分割
要么全部执行成功,要么全部执行失败。
C:consistence 一致性事务前后的数据要保存一致:比如转账前后总金额要一致。
I:isolation 隔离性多个事务之间操作不能相互影响。
D:durablity 持久性事务一旦提交则对数据库的数据影响是永久的,不可逆了。

24-事务的隔离级别-[★]

  • 并发访问存在问题
并发访问的问题含义
脏读一个事务读取到了另一个事务中尚未提交的数据
不可重复读一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是一致 的,这是事务update时引发的问题
幻读一个事务中两次读取的数据的数量不一致,要求在一个事务多次读取的数据的数量是 一致的,这是insert或delete时引发的问题
  • 隔离级别
级别名字隔离级别脏读不可重复读幻读数据库默认隔离级别
1读未提交read uncommitted
2读已提交read committedOracle和SQL Server
3可重复读repeatable readMySQL
4串行化serializable

查询全局事务隔离级别

select @@transaction_isolation;
– 或
select @@tx_isolation;

修改隔离级别:

set global transaction isolation level 级别字符串;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值