oracle+mysql+锁实现_Oracle数据库死锁和MySQL死锁构造和比较

本文对比了Oracle和MySQL在事务隔离性方面的表现,并详细介绍了如何在两种数据库中构造死锁场景。对于Oracle,文中展示了如何创建测试表并触发死锁;而对于MySQL,探讨了其默认的可重复读隔离级别及在缺少索引时InnoDB如何退化为表级锁的问题。

最近在复习数据库的事务隔离性,顺便构造了一下在Oracle上和MySQL上的死锁以比较异同。

在Oracle上面的实验

在Oracle中,因为是显式提交,所以默认可以认为在一个会话中若没有使用commit进行提交,则可以认为在同一个事务里面

首先构造测试用表

SQL> create table t(a1 number,b varchar2(10), c varchar2(10));

SQL> insert into t1 (1,'a','b');

SQL> insert into t values (2, 'aa','bb');

开两个窗口形成死锁

7e494fe6ba0e2e0fd0e4ab5e7b2483df.png

同时这个过程中,可以在第三会话中进行查询,未提交的数据是不能够被查看到的。

在MySQL上的实验

使用的版本

mysql> statusmysql Ver 14.14 Distrib 5.6.26, for Linux (x86_64) using EditLine wrapper

Connection id: 2

Current database: test

Current user: root@localhost

SSL: Not in use

Current pager: stdout

Using outfile: ''

Using delimiter: ;

Server version: 5.6.26 MySQL Community Server (GPL)

Protocol version: 10

Connection: Localhost via UNIX socket

Server characterset: latin1

Db characterset: latin1

Client characterset: utf8

Conn. characterset: utf8

UNIX socket: /var/lib/mysql/mysql.sock

Uptime: 4 hours 52 min 1 sec

Threads: 3 Questions: 107 Slow queries: 0 Opens: 69 Flush tables: 1 Open tables: 62 Queries per second avg: 0.006

mysql> show variables like '%isolation%';

+---------------+-----------------+

| Variable_name | Value |

+---------------+-----------------+

| tx_isolation | REPEATABLE-READ |

+---------------+-----------------+

1 row in set (0.00 sec)

在MySQL中,默认采用repeatable read的隔离级别,且在事务执行过程中使用的是隐式提交,所以需要显式指定事务。根据《高性能MySQL》书中第5页的方式试图构造出死锁。

41b1e64951a1a3b860d429b494535332.png

这时,可以发现问题,此时innodb竟然执行的不是row lock而是table lock。 这个问题已经在stackoverflow上面进行提问, 获得的解答是必须在表上增加一个主键或者索引,否则innodb无法判断准确的行信息,就无法实现行级锁。

比如,通过可以通过锁升级造成锁队列阻塞。

d43f0388ba565c90146011d8632dd06c.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值