banner
NEWS LETTER

数据管理技术-Lab-8

Scroll down

数据管理技术Lab8实验报告

Task1:隔离级别的验证

使用命令行工具连接 MySQL 或使用可视化工具,实验需要设计 2个 MySQL session,对应为 2 个建立连接的命令行窗口或可视化工具中 2 个会话框;

建表:

1
2
3
4
5
6
7
CREATE TABLE account (
id int NOT NULL PRIMARY KEY,
name varchar(10) DEFAULT NULL,
money int DEFAULT 0
);
INSERT into account values(1, ‘tom’, 1000);
INSERT into account values(2, ‘bob’, 0);

隔离级别:
1.read uncommitted
2.read committed
3.repeatable read
4.Serializable

Q1:

按照表格顺序执行,给出语句2、语句4和语句5的输出结果,并分析结果

语句2

语句4:

语句5:

分析结果:

读未提交的概念:允许一个事务可以看到其他事务未提交的修改。

语句2证明tom的money加了1000,而语句4在事务1提交前读tom对应行,由于设定为read uncommitted,虽然事务1未提交,但事务2可以读到事务1的更新值为2000。在事务1roll back后,事务2又读出money为1000.

Q2:

将语句1,语句3的隔离级别修改为 read committed / repeatable read / serializable,重新执行,记录语句2、语句4和语句5的输出结果,并分析结果

read committed

语句2:

语句4:

语句5:

分析结果:

读已提交的概念:允许一个事务只能看到其他事务已经提交的修改,未提交的修改是不可见的。

语句2证明tom的money加了1000,而语句4在事务1提交前读tom对应行,由于设定为read committed,且事务1未提交,但事务2只能读到事务1更新前的值为1000。在事务1roll back后,事务2又读出money为1000。不会脏读。

repeatable read

语句2:

语句4:

语句5:

分析结果:

可重复读概念:确保如果在一个事务中执行两次相同的select语句,都能得到相同的结果,不管其他事务是否提交这些修改。

事务2读到的内容是事务2开始前的内容,即使在事务进行中有其他事务commit也不会改变事务2读到的内容。在本例中体现不明显。不会脏读。

serializable

语句2:

语句4:

语句5:

分析结果:

Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,所有操作都是阻塞被同步调用的。可以避免脏读、不可重复读与幻读

语句2证明tom的money加了1000,而语句4在事务1提交前读tom对应行,由于设定为serializable ,且事务1未提交,因此事务2被阻塞,直到事务1提交后,事务2才可以继续执行。不会脏读。

Q3:

按照表格顺序执行,给出语句2和语句4的输出结果,并分析结果

语句2:

语句4:

分析结果:

语句2先读出id为2的行,此时事务2修改id为2的行的money为1000并提交,由于隔离级别为read committed,语句4读出事务2修改后的行,这证明了read committed是不可重复读的。

Q4:

将语句1,语句3的隔离级别修改为 repeatable read / serializable,重新执行,记录语句2和语句4的输出结果,并分析结果

repeatable read

语句2:

语句4:

分析结果:

语句2先读出id为2的行,此时事务2修改id为2的行的money为1000并提交,由于隔离级别为repeatable read,即使事务2提交,也不会改变事务1读到的内容。因此repeatable read是可重复读的。

serializable

语句2:

语句4:

分析结果:

语句2先读出id为2的行,此时事务2修改id为2的行的money为1000并提交,由于隔离级别为serializable,因此只有在事务1提交后事务2中的语句才会被执行,因此

update account set money = money+1000 where id=2;这个语句会被阻塞直到事务1 提交。

Q5:

按照表格顺序执行,给出T2与T4时刻语句2的输出结果与状态,并解释其原因;

T2时刻:

T4时刻:

分析结果:

T2时刻事务1上锁,事务2想要改变数据,但此时事务1占据了锁,因此事务2被阻塞。T4时刻事务1已提交,事务2顺利执行。

Q6:

按照表格顺序执行,给出语句2和语句4的输出结果

语句2:

image-20230517174217512

语句4:

分析结果:

事务2对数据库进行修改,但是事务1前后读内容相同,这是因为repeatable read前后读的内容不会改变。

Q7:

将语句1,语句3的隔离级别修改为 serializable,重新执行,记录语句2和语句4的输出结果

语句2:

语句4:

由于串行化影响,事务2的操作需要等待事务1提交后才可以执行,因此语句2和语句4结果相同。

Q8:

若语句2 增加了 lock in share mode; 的设置,T2中语句 5、6 会阻塞;请结合两种隔离级别下解锁前后的现象,分析阻塞原因。

repeatable read

serializable

分析结果:

事务2中的语句都被阻塞,这是因为lock in share mode对数据库加S锁,而事务2中的insert语句尝试对其加X锁,失败而处于阻塞状态。

Q9:

按照表格顺序执行,给出语句2、语句3的执行结果,并分析原因

语句2:

语句3:

事务1在执行update语句时对数据库加了X锁,不能再加锁,事务2的delete

语句尝试对数据库加X锁,因此delete被阻塞,直到事务1提交后语句2、3才能执行。

Task2:死锁

使用命令行工具连接 MySQL 或使用可视化工具,实验需要设计 2个 MySQL session,对应为 2 个建立连接的命令行窗口或可视化工具中 2 个会话框;
建表:
create tableA(id, columnA) …
create tableB(id, columnB) …
Insert into tableA values(1, 0);
Insert into tableB values(1, 0);
开启两个命令行界面A和B,按照下面顺序在A、B中分别执行语句:
A: start transaction;(或Begin)
A: update tableA set columnA=1 where id=1;
B: start transaction;
B: update tableB set columnB=2 where id=1;
A: update tableB set columnB=3 where id=1;
B: update tableA set columnA=2 where id=1;
最后一条语句执行时系统会提示死锁,界面A会处于等待状态,需要手工杀掉死锁事务

Q10: 请解释死锁发生的原因,并按照链接方法手工杀死死锁事务

手动解除:

事务1对tableA加锁,之后事务2又对tableB加锁,在两个事务还没有释放锁之前,事务1又请求对tableB加锁,被阻塞,事务2对tableB申请加锁,被阻塞,两个事务都是在占有一部分资源后申请另一部分资源,从而两个事务都被阻塞,因此产生死锁。

其他文章
cover
OS-Lab6
  • 23/05/19
  • 22:53
  • 1.4k
  • 5