Compare PostgreSQL and Oracle dead lock detect and transaction
2011-05-25 07:31
309 查看
Oracle 和 PostgreSQL的死锁检测和处理有较大区别。
主要差别在于 :
1.
死锁被检测到的属于哪个SESSION?Oracle随机检出,从实验来看应该是第一个启动的死锁事务。而PostgreSQL是死锁发生时的最后一个事
务,与ORACLE相反(从PG的deadlock_timeout参数可以看出PostgreSQL的死锁检测不是随机的,而是可预见的。This
is the amount of time, in milliseconds, to wait on a lock before
checking to see if there is a deadlock condition.)。
2. 死锁被检测到之后的处理上的差别,oracle允许单个事务中的部分SQL执行成功,部分SQL执行失败(其实这是非常严重的缺陷)。而PostgreSQL不允许事务中的部分SQL语句执行成功,要么全部成功,要么全部失败。
如图:
PostgreSQL 模拟死锁场景和检测结果,
![](http://img617.ph.126.net/TGoV34X4NxxJDFLix22XnQ==/1657606137850824582.jpg)
Oracle 模拟死锁场景和检测结果,
![](http://img624.ph.126.net/EvjkCxdvwsg3YgHBDlDY3A==/3010374875922210524.jpg)
PostgreSQL参数 :
deadlock_timeout = 1s
死锁检查会消耗部分数据库资源,如果数据库压力比较大的话可以考虑调大这个值。
SESSION A :
digoal=> begin;
BEGIN
Time: 0.122 ms
digoal=> update tbl_test set id=id+1 where id=100;
UPDATE 1
Time: 0.379 ms
SESSION B :
digoal=> begin;
BEGIN
Time: 0.126 ms
digoal=> update tbl_test2 set id=id+1 where id=100;
UPDATE 1
Time: 0.437 ms
SESSION C :
digoal=> begin;
BEGIN
digoal=> update tbl_test1 set id=id+1 where id=100;
UPDATE 1
SESSION A :
digoal=> update tbl_test2 set id=id+2 where id=100;
SESSION B :
digoal=> update tbl_test1 set id=id+3 where id=100;
SESSION C :
digoal=> update tbl_test set id=id+4 where id=100;
ERROR: deadlock detected
DETAIL: Process 11953 waits for ShareLock on transaction 4232; blocked by process 2873.
Process 2873 waits for ShareLock on transaction 4233; blocked by process 6616.
Process 6616 waits for ShareLock on transaction 4234; blocked by process 11953.
HINT: See server log for query details.
SESSION B :
UPDATE 1
Time: 7839.728 ms
SESSION A :
UPDATE 0
Time: 40903.601 ms
digoal=> commit;
COMMIT
Time: 0.099 ms
SESSION C :
digoal=> commit;
ROLLBACK
Time: 0.196 ms
注意到在PostgreSQL中,整个SESSION C回滚了。
Oracle :
SESSION A:
SQL> update tbl_test set id=id+1 where id=100;
1 row updated.
Elapsed: 00:00:00.00
SESSION B:
SQL> update tbl_test2 set id=id+1 where id=100;
1 row updated.
Elapsed: 00:00:00.01
SESSION C:
SQL> update tbl_test1 set id=id+1 where id=100;
1 row updated.
Elapsed: 00:00:00.00
SESSION A:
SQL> update tbl_test2 set id=id+2 where id=100;
SESSION B:
SQL> update tbl_test1 set id=id+3 where id=100;
0 rows updated.
Elapsed: 00:00:39.50
SESSION C:
SQL> update tbl_test set id=id+4 where id=100;
0 rows updated.
Elapsed: 00:00:17.34
SESSION A:
update tbl_test2 set id=id+2 where id=100
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
Elapsed: 00:00:18.05
SESSION A:
SQL> commit;
Commit complete.
Elapsed: 00:00:00.01
SESSION B:
SQL> commit;
Commit complete.
Elapsed: 00:00:00.00
SESSION C:
SQL> commit;
Commit complete.
Elapsed: 00:00:00.01
显然,ORACLE的SESSION A检测到了死锁,并且COMMIT后SESSION A部分SQL执行成功。
SQL> select * from tbl_test where id>=100;
ID
----------
101
Elapsed: 00:00:00.00
Oracle 允许事务中部分SQL执行成功,部分失败的严重缺陷 :
举个简单的例子:充值。
A花了100元购买100个斯凯币。
update tbl_account_rmb set amount=amount-100 where id='A';
success
update tbl_account_kb set amount=amount+100 where id='A';
deadlock,failed.
commit;
此时A的100元花出去了,但是KB没有充值到账。
主要差别在于 :
1.
死锁被检测到的属于哪个SESSION?Oracle随机检出,从实验来看应该是第一个启动的死锁事务。而PostgreSQL是死锁发生时的最后一个事
务,与ORACLE相反(从PG的deadlock_timeout参数可以看出PostgreSQL的死锁检测不是随机的,而是可预见的。This
is the amount of time, in milliseconds, to wait on a lock before
checking to see if there is a deadlock condition.)。
2. 死锁被检测到之后的处理上的差别,oracle允许单个事务中的部分SQL执行成功,部分SQL执行失败(其实这是非常严重的缺陷)。而PostgreSQL不允许事务中的部分SQL语句执行成功,要么全部成功,要么全部失败。
如图:
PostgreSQL 模拟死锁场景和检测结果,
![](http://img617.ph.126.net/TGoV34X4NxxJDFLix22XnQ==/1657606137850824582.jpg)
Oracle 模拟死锁场景和检测结果,
![](http://img624.ph.126.net/EvjkCxdvwsg3YgHBDlDY3A==/3010374875922210524.jpg)
PostgreSQL参数 :
deadlock_timeout = 1s
死锁检查会消耗部分数据库资源,如果数据库压力比较大的话可以考虑调大这个值。
SESSION A :
digoal=> begin;
BEGIN
Time: 0.122 ms
digoal=> update tbl_test set id=id+1 where id=100;
UPDATE 1
Time: 0.379 ms
SESSION B :
digoal=> begin;
BEGIN
Time: 0.126 ms
digoal=> update tbl_test2 set id=id+1 where id=100;
UPDATE 1
Time: 0.437 ms
SESSION C :
digoal=> begin;
BEGIN
digoal=> update tbl_test1 set id=id+1 where id=100;
UPDATE 1
SESSION A :
digoal=> update tbl_test2 set id=id+2 where id=100;
SESSION B :
digoal=> update tbl_test1 set id=id+3 where id=100;
SESSION C :
digoal=> update tbl_test set id=id+4 where id=100;
ERROR: deadlock detected
DETAIL: Process 11953 waits for ShareLock on transaction 4232; blocked by process 2873.
Process 2873 waits for ShareLock on transaction 4233; blocked by process 6616.
Process 6616 waits for ShareLock on transaction 4234; blocked by process 11953.
HINT: See server log for query details.
SESSION B :
UPDATE 1
Time: 7839.728 ms
SESSION A :
UPDATE 0
Time: 40903.601 ms
digoal=> commit;
COMMIT
Time: 0.099 ms
SESSION C :
digoal=> commit;
ROLLBACK
Time: 0.196 ms
注意到在PostgreSQL中,整个SESSION C回滚了。
Oracle :
SESSION A:
SQL> update tbl_test set id=id+1 where id=100;
1 row updated.
Elapsed: 00:00:00.00
SESSION B:
SQL> update tbl_test2 set id=id+1 where id=100;
1 row updated.
Elapsed: 00:00:00.01
SESSION C:
SQL> update tbl_test1 set id=id+1 where id=100;
1 row updated.
Elapsed: 00:00:00.00
SESSION A:
SQL> update tbl_test2 set id=id+2 where id=100;
SESSION B:
SQL> update tbl_test1 set id=id+3 where id=100;
0 rows updated.
Elapsed: 00:00:39.50
SESSION C:
SQL> update tbl_test set id=id+4 where id=100;
0 rows updated.
Elapsed: 00:00:17.34
SESSION A:
update tbl_test2 set id=id+2 where id=100
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
Elapsed: 00:00:18.05
SESSION A:
SQL> commit;
Commit complete.
Elapsed: 00:00:00.01
SESSION B:
SQL> commit;
Commit complete.
Elapsed: 00:00:00.00
SESSION C:
SQL> commit;
Commit complete.
Elapsed: 00:00:00.01
显然,ORACLE的SESSION A检测到了死锁,并且COMMIT后SESSION A部分SQL执行成功。
SQL> select * from tbl_test where id>=100;
ID
----------
101
Elapsed: 00:00:00.00
Oracle 允许事务中部分SQL执行成功,部分失败的严重缺陷 :
举个简单的例子:充值。
A花了100元购买100个斯凯币。
update tbl_account_rmb set amount=amount-100 where id='A';
success
update tbl_account_kb set amount=amount+100 where id='A';
deadlock,failed.
commit;
此时A的100元花出去了,但是KB没有充值到账。
相关文章推荐
- Compare dblink module Within One Transaction in PostgreSQL,EnterpriseDB and Oracle
- Transaction (Process ID ) was deadlocked on lock resources with another process and has been chosen
- Transaction (Process ID) was deadlocked on lock resources with another process and has been chose
- Transaction And Lock--事务中使用return会回滚事务吗?
- Oracle Lock and Hibernage Lock
- Notes: Process in Operation System and Dead Lock 操作系统中的进程和死锁问题
- 无锁的数据结构(Lock-Free)及CAS(Compare-and-Swap)机制
- Transaction And Lock--唯一索引下INSERT导致的死锁
- Transaction And Lock--存在嵌套事务吗?
- oracle and postgresql join method
- Transaction And Lock--使用资源锁来控制并发
- About transaction lock and V$lock view
- Notes: Process in Operation System and Dead Lock 操作系统中的进程和死锁问题
- Transaction And Lock--两种方式实现可重复读
- Transaction And Lock--锁相关基础
- Notes: Process in Operation System and Dead Lock 操作系统中的进程和死锁问题
- orafce extension for PostgreSQL, Oracle's compatibility functions and packages
- Transaction And Lock--已提交读快照
- Comparison of Oracle, MySQL and PostgreSQL DBMS
- Notes: Process in Operation System and Dead Lock 操作系统中的进程和死锁问题