JDBC和数据库事务详解(二)

行锁

假设每个数据行支持两种锁RS和RX;RS表示Row Share,行共享锁,不同的连接可以对同一行记录同时上RS锁,即行共享锁,多个连接被允许同时对一条记录上共享锁;RX表示Row Exclusive,即行排它锁,只能有一个连接可以对一行记录上RX锁。另外,锁可以升级,如果期望给一行数据上RX锁而当前行已经存在一个RS锁,那么RS所会升级成RX锁。但是反过来,锁不能降低级,如果已经存在RX锁,希望上一个RS锁,那么必须等待解锁。

已存在行锁期望新加行锁执行方式
nullRS成功,加上RS锁
nullRX成功,加上RX锁
RSRS成功,因为RS是共享的,多个连接可同时锁
RSRX成功,因为RS锁支持升级为RX锁
RX(其它连接加的)RS等待解锁再上锁,因为RX是排它的,可能超时
RX(同一连接加的)RS忽略操作直接完成,锁保持RX不变
RX(其它连接加的)RX等待解锁再上锁,因为RX是排它的,可能超时
RX(同一连接加的)RX忽略操作直接完成,锁保持RX不变

表锁

类似地,对一张表级别的锁而言, 也有两种锁TS和TX,工作原理RS, RX非常类似,不再描述

修改语句和悲观锁查询语句的行锁和表锁

对于修改语句,典型如下:

INSERT INTO MY_TABLE(C1, C2, …, CN) VALUES(V1, V2, …, VN);
UPDATE MY_TABLE SET C1 = V1, C2 = V2, … CN = VN WHERE C1 = OV1;
DELETE FROM MY_TABLE WHERE C1 = V1;
他们所对应的锁行为都是:
1. 首先对MYT_TABLE表上TS锁
2. 再对被插入或修改的所有行上RX锁(删除后无行,行锁操作忽略)。

任何隔离级别下的悲观锁查询

SELECT … FOR UPDATE
均如此工作:
1. 首先在对被查询的表上TS锁
2. 再对查询到的所有行上RX锁。
可以发现,悲观锁查询和类似修改语句

普通查询的行锁和表锁

普通查询语句在不同的隔离级别下工作机制不一样
(1)如果当前连接的隔离级别为未提交读。不进行任何行锁和表锁的操作,无论表或数据行是否有锁以及是什么锁,均不理会,直接无条件取。
(2)如果当前连接的隔离级别为提交读。对所有被查到的行上RS锁。如果其它连接已经使用修改或悲观锁查询让相同行具备了RX锁,因为RX无法降级为RS,必须等待其它连接解锁才能返回查询结果,从而保证不会读到未提交数据。
(3)如果当前连接的隔离级别为可重复读。先对表上TS锁,然后对对所有被查到的行上RX锁。从而保证其它连接不能对相同的数据行上RX锁进行修改或悲观锁查询
(4)序列化读隔离级别,直接对表上TX锁,直接阻止其它连接对表上TS锁,即其他连接不能对同一张表的任何数据行进行修改或悲观锁查询

在一般的数据库事务中,一个事务就代表着一个链接,事务的隔离级别既是链接的隔离级别,不同的锁行为即代表了不同的执行效率,这点是需要大家透彻理解的。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页