数据管理技术Lab8实验报告
Task1:隔离级别的验证
使用命令行工具连接 MySQL 或使用可视化工具,实验需要设计 2个 MySQL session,对应为 2 个建立连接的命令行窗口或可视化工具中 2 个会话框;
建表:
1 | CREATE TABLE account ( |
隔离级别:
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:
语句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申请加锁,被阻塞,两个事务都是在占有一部分资源后申请另一部分资源,从而两个事务都被阻塞,因此产生死锁。