create table student(sid int,sname varchar);
create table student1(sid int,sname varchar);
begin
for i in 4000..10000 loop
insert into student values(i,'学生i'||i);
insert into student1 values(i,'学生i'||i);
end loop;
commit;
end
/
--session1
UPDATE student SET sname = 'student1' WHERE sid = 1;
--session2
UPDATE student1 SET sname = 'student1' WHERE sid = 1;
--session1
UPDATE student1 SET sname = 'student1' WHERE sid = 1;
--执行出现阻塞
--session2
UPDATE student SET sname = 'student1' WHERE sid = 1;
--报错死锁,语句回滚
--session1继续等待,直到session2事务提交或回滚
在数据库管理系统中,根据锁获取和释放的时机来区分,封锁通常有一次封锁协议和两阶段封锁协议。为了实现并发调度的可串行性,通常采用两阶段封锁协议保证调度的正确性。
两段锁协议将每个事务的执行分为两个阶段:生长阶段(加锁阶段)和衰退阶段(解锁阶段)。一次封锁法要求事务在开始执行时一次获取所有需要的锁,执行完毕后一次性释放所有锁。相比一次封锁法,两阶段封锁法按需申请锁,提供了更高的并发性。然而,并非所有事务都是可串行化的,两阶段提交在资源使用上虽然更加灵活,但是事务在需要时申请锁,这可能会与其他事务形成循环等待,从而导致死锁。
从上述例子中,可以看到死锁是在两个事务相互等待对方持有的资源时产生的。这种情况会导致事务无法继续执行,形成一个死循环。在DM数据库中,会周期性地检测死锁情况。当检测到死锁时,选择一个或多个事务进行回滚,释放锁资源,从而打破死锁。
文章
阅读量
获赞