UPDATE employees UPDATE employees
SET salary = salary x 1.1 SET salary = salary x 1.1
WHERE employee_id = 1000; WHERE employee_id = 2000;
UPDATE employees UPDATE employees
SET manager = 1342 SET manager = 1342
WHERE employee_id = 2000; WHERE employee_id = 1000;比如象这样情况下,会发生DEADLOCK.此时系统应该会自动检查到它并解决它.
那么,系统是怎样解决的呢? 系统如何判断该回退哪个用户的语句呢?
SET salary = salary x 1.1 SET salary = salary x 1.1
WHERE employee_id = 1000; WHERE employee_id = 2000;
UPDATE employees UPDATE employees
SET manager = 1342 SET manager = 1342
WHERE employee_id = 2000; WHERE employee_id = 1000;比如象这样情况下,会发生DEADLOCK.此时系统应该会自动检查到它并解决它.
那么,系统是怎样解决的呢? 系统如何判断该回退哪个用户的语句呢?
但是在之前的操作并不会撤掉,需要用户主动commit或者rollback来完成操作用户1:
SQL> update st_course set grade=grade+1 where cno = 1;已更新 1 行。SQL> update st_course set grade=grade+2 where cno=2;
update st_course set grade=grade+2 where cno=2
*
ERROR 位于第 1 行:
ORA-00060: 等待资源时检测到死锁
SQL> select * from st_course; SNO CNO GRADE
---------- ---------- ----------
2007001 1 93
2007001 2 85
2007001 3 88
2007002 2 90
2007002 3 80用户2:
SQL> update st_course set grade=grade+3 where cno = 2;已更新2行。SQL> update st_course set grade=grade+4 where cno = 1;
update st_course set grade=grade+4 where cno = 1
*
ERROR 位于第 1 行:
ORA-00060: 等待资源时检测到死锁
SQL> select * from st_course; SNO CNO GRADE
---------- ---------- ----------
2007001 1 92
2007001 2 88
2007001 3 88
2007002 2 93
2007002 3 80
在之后,用户1或者用户2执行commit以后,他们的第一个更新操作都会生效,但是第二个形成死锁的就失败了。不管怎样,用户必须手动commit或rollback来完成操作。
然后必须由两个用户之一执行提交或回退而使另外一个用户的操作可以成功.
那么你有没有想过这种情况,如果在两个用户的第2个操作都失败后,他们并不知道这是造成了死锁,而是继续进行更新操作 ,那么就又会造成死锁.完了就又是操作失败.........如此循环下去
是不是该有DBA来通知这两个用户要提交或回退他们的第1个操作呢?
如果这时会话1执行ROLLBACK,则会话1的第一条SQL语句会被ROLLBACK .如果执行的是COMMIT语句的话,则会话1的第一条SQL语句会被提交.只有在会话1执行了(ROLLBACK/COMMIT)之后,会话2才能得到相应的锁资源,进行处于可操作的状态.而会话2的两条SQL语句都在等待用户的事务操作语句(ROLLBACK/COMMIT),如果会话2执行ROLLBACK ,则会话2的两条SQL语句都被ROLLBACK ,而如果
会话2执行的是COMMIT语句,则会话2的两条语句都会被提交.
出了问题虽然不是你的错,可起码你有职责通知该用户进行改正,不然仍然会造成死锁而是更多的用户无法进行正常的工作