数据库事务 - 怎样才能产生 互相等待 - 死锁,怎么解决
2017-03-14 18:29
363 查看
数据库事务 - 怎样才能产生 互相等待 - 死锁,如何解决
1. 最简单的死锁
最常见的死锁 是因为一个事务执行时间过长,而导致另外一个事务 无法 访问 被被该事务锁定的资源,最终 超时 而导致的死锁异常. 这种情况无非有两种解决方案,一是性能调优。 二是当该事务遇到等待超时导致的死锁异常后,继续让该事务 re-try.
2. 互相等待 -- 死锁
这种 死锁的异常情况特殊,两个极短的事务 在 高并发的环境下也可能发生 相互等待 -- 死鎖 的情況.
a) 怎样导致的?
总的来说,是因为两个事务 对共有资源的CUD 执行顺序 不同导致的. 如下,
事务1: A -- > B
事务2: B -- > A
在高并发情况下,如果 相同时间内,事务1 处理完 对资源A的CUD 同时 事务2 处理完 对资源B 的CUD。 这个时候 事务1 要对 B 资源 CRUD 同时 事务2也要对 A资源 CRUD, 而此时, 事务1 锁住了A资源,事务2锁住了B资源,所以 事务1需要等待事务2释放B资源 才能继续对B资源操作,相反事务2需要等待事务1释放A资源 才能继续对A资源操作。 这样 两个事务互相等待 锁释放 而导致死锁
b) 如何解決?
唯一的办法就是 让这两个事务 对共有资源的CUD 执行顺序 一样。
事务1: A -- > B
事务2: A -- > B
有趣的问题 如果事务2 是 A --> B --> A 而事务1保持不变, 当事务2 执行完B资源操作 再次对A资源操作的时候 会不会出现死锁呢, 看起来如果事务1同时也执行到对B资源操作的时候 - 好像会, 但答案是不会.
原因很简单,因为 A资源已经被 事务2 锁定, 事务1 不会有机会启动,只有等待 事务2 释放 A资源锁后,得到该锁的事务1才能开始执行。
同样, 如果我们 这样设定执行的顺序来解决这样的问题,是不是会导致 线程相互等待的时间过长 而导致性能大幅降低呢 ?( 如事务2 先执行,那么事务1就必须等待 事务2执行完后,释放对A 资源的锁后, 得到该锁的事务1 才能继续执行)
我们完全没必要有这种担忧, 原因很简单,大型系统中, 即便是在高并发状态下,两个或者多个不同线程的事务 能同时在千万条数据中 并发访问到(这里指 CUD 操作)完全相同的数据 的概率是相当小的 。
产生死锁的必要条件 虽然进程在运行过程中,可能发生死锁,但死锁的发生也必须具备一定的条件,死锁的发生必须具备以下四个必要条件 。
1 )互斥条件: 指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2 )请求和保持条件: 指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3 )不剥夺条件: 指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。(既是没有Timeout 或者 更高优先级剥夺 的情况)
4 )环路等待条件: 指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
死锁的详细说明
1. 最简单的死锁
最常见的死锁 是因为一个事务执行时间过长,而导致另外一个事务 无法 访问 被被该事务锁定的资源,最终 超时 而导致的死锁异常. 这种情况无非有两种解决方案,一是性能调优。 二是当该事务遇到等待超时导致的死锁异常后,继续让该事务 re-try.
2. 互相等待 -- 死锁
这种 死锁的异常情况特殊,两个极短的事务 在 高并发的环境下也可能发生 相互等待 -- 死鎖 的情況.
a) 怎样导致的?
总的来说,是因为两个事务 对共有资源的CUD 执行顺序 不同导致的. 如下,
事务1: A -- > B
事务2: B -- > A
在高并发情况下,如果 相同时间内,事务1 处理完 对资源A的CUD 同时 事务2 处理完 对资源B 的CUD。 这个时候 事务1 要对 B 资源 CRUD 同时 事务2也要对 A资源 CRUD, 而此时, 事务1 锁住了A资源,事务2锁住了B资源,所以 事务1需要等待事务2释放B资源 才能继续对B资源操作,相反事务2需要等待事务1释放A资源 才能继续对A资源操作。 这样 两个事务互相等待 锁释放 而导致死锁
b) 如何解決?
唯一的办法就是 让这两个事务 对共有资源的CUD 执行顺序 一样。
事务1: A -- > B
事务2: A -- > B
有趣的问题 如果事务2 是 A --> B --> A 而事务1保持不变, 当事务2 执行完B资源操作 再次对A资源操作的时候 会不会出现死锁呢, 看起来如果事务1同时也执行到对B资源操作的时候 - 好像会, 但答案是不会.
原因很简单,因为 A资源已经被 事务2 锁定, 事务1 不会有机会启动,只有等待 事务2 释放 A资源锁后,得到该锁的事务1才能开始执行。
同样, 如果我们 这样设定执行的顺序来解决这样的问题,是不是会导致 线程相互等待的时间过长 而导致性能大幅降低呢 ?( 如事务2 先执行,那么事务1就必须等待 事务2执行完后,释放对A 资源的锁后, 得到该锁的事务1 才能继续执行)
我们完全没必要有这种担忧, 原因很简单,大型系统中, 即便是在高并发状态下,两个或者多个不同线程的事务 能同时在千万条数据中 并发访问到(这里指 CUD 操作)完全相同的数据 的概率是相当小的 。
产生死锁的必要条件 虽然进程在运行过程中,可能发生死锁,但死锁的发生也必须具备一定的条件,死锁的发生必须具备以下四个必要条件 。
1 )互斥条件: 指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2 )请求和保持条件: 指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3 )不剥夺条件: 指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。(既是没有Timeout 或者 更高优先级剥夺 的情况)
4 )环路等待条件: 指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
死锁的详细说明
相关文章推荐
- 怎样才能把一个代码变成软件成品?一个初学者的困惑,我们写的代码都只能是解决一些数学问题而已。怎么把它变成一个软件。
- 数据库的读读事务也会产生死锁
- 如果数据库处于归档模式但自动归档功能没有开启会产生什么后果呢,产生这种情况后又怎样解决呢?
- mysql死锁,等待资源,事务锁,Lock wait timeout exceeded; try restarting transaction解决
- 屏幕录像专家V7.5怎么录的不清楚,怎样才能录制清晰呢【已解决】
- mysql死锁,等待资源,事务锁,Lock wait timeout exceeded; try restarting transaction解决
- SQL2005删除用户时,产生“数据库主体在该数据库中拥有架构,无法删除”的解决办法
- 当需要2个事务才能完成一个完整业务时,回滚解决办法!抛砖引玉
- java 连接 mysql 数据库"javax.servlet.ServletException: org.gjt.mm.mysql.Driver"是什么问题,怎样解决?
- 怎样快速查出Oracle 数据库中的锁等待
- SQL2005删除用户的时候,产生“数据库主体在该数据库中拥有架构,无法删除”的解决办法
- ※如何解决Struts中的ActionErrors怎么才能在页面上显示出来的问题?※
- 怎样解决配置Oracle OEM时找不到数据库节点的问题
- 事务死锁的问题如何解决?
- 中死锁产生的原因及解决办法
- 关于VC操作Excel和运用ADO操作数据库时产生冲突的解决
- "请备份该数据库的事务日志以释放一些日志空间"解决方法 推荐
- 怎样快速查出Oracle 数据库中的锁等待[转贴]
- 怎样快速查出Oracle 数据库中的锁等待
- 跨数据库事务的解决