Oracle数据库—锁和表

:是用来保护正在被修改的数据,直到提交或者回滚事务之后,其他用户才可以更新数据。

锁的优点是:

一致性:一次只允许一个用户修改数据。

完整性:为所有用户提供正确的数据。也就是说,当一个用户修改并且保存所做的修改之后,将反映给所有的用户。

并发性:永续多个用户访问同一数据。

锁的有两种分类:一个是行级锁,一个是表级锁。

行级锁也是一种排他锁,对正在被修改的行进行锁定,会保证在同一时刻不允许其他用户修改同一行数据,用户只能访问除此行之外的数据。当涉及到 insert、update、delete、select…for update 时,会自动应用行级锁。下面重点讲解一下 select…for update。

语法:select…for update [of column_list] [wain n | nowait]

Of子句用于指定预先被更新的列。

Wait或nowait: wait制定等待等待他们用户释放锁的秒数。防止无限期等待。Nowait表示不等待。

通过一个例子讲解一下:

select *from  tbl_category where categoryid=2 forupdate;

用scott表示锁定了tbl_category中的categoryid为2的这一行

切换用户为abxl登录,再去访问这一行

select *from  scott.tbl_category wherecategoryid=2 for update wait 1;

则提示一下错误, wait 1 表示 只等待一秒。 nowait表示直接显示,不等待。

第 1 行出现错误:

ORA-30006: 资源已被占用; 执行操作时出现 WAIT 超时

当scott用户发出 commit或者rollback时才释放锁,其他用户才可以更新该行数据。

表级锁将锁定的是整张表,在锁定中限制其他用户对整个表的访问。语法是:

LOCK TABLEtable_name IN lock_name MODE [nowait]

Lock_name是锁定的模式。

nowait防止无限期等待其他用户释放资源。

表级锁包含:

行共享(ROW SHARE, RS):允许其他用户访问或锁定该表,但是禁止排他锁定整个表使用select…for update语句会在表上自动应用行共享。

行排他(ROW EXCLUSIVE, RX):和行共享相同,同时禁止其他用户在此表上使用行共享。

共享锁(SHARE, S):仅允许其他用户查询表中的行,但是不允许插入、更新和删除。多个用户可以同时在同一张表上添加共享锁。

共享行排他锁(SHARE ROW EXCLU, SRX):执行比共享锁更多的限制。防止在表上应用共享锁。

排他锁(EXCLUSIVE, X):对表执行最大的限制。除了允许其他用户查询该表数据,将不允许做任何操作和添加任何锁。

死锁处理

Create table A(X number); 创建两个表,并且插入数据

Create table B(Xnumber);

Insert into Avalues(1);

Insert into Bvalues(1);

Update A setx=x+1;scott用户更新A表

Update B setx=x+; abxl用户更新B表

Update A setx=x+;abxl用户更新A表

Update B setx=x+;scott用户更新B表

就会导致死锁,两个会话中会有一个被选为“牺牲者”,它的语句将会被回滚,并返回错误信息。

表分区允许用户把一个表中的所有数据分成几个部分,并将这些部分存储在不同的位置,被分区的表成为分区表,分成的每一个部分成为一个分区。

优点是:提高数据库的可管理型,提高数据库的性能,提高可用性。

有四种分区的方法

范围分区,散列分区,列表分区,复合分区。

范围分区:

create tabletbl_tag

( tagidnumber(10) not null,

  tag varchar2(50) not null,

  count number(10) not null,

  constraint"tbl_tag_tagid_pk"primary key(tagid)

)

  partition by range(count)

  (

  partition tag_p1 values less than (1000),

  partition tag_p2 values less than (3000),

  partition tag_p3 values less than (maxvalue)

);

散列分区:

create tabletbl_tag

( tagidnumber(10) not null,

  tag varchar2(50) not null,

  count number(10) not null,

  constraint"tbl_tag_tagid_pk"primary key(tagid)

)

 Partition by hash ( tagid)

Partitions 8;   平均分成8份

 

create tabletbl_tag

( tagidnumber(10) not null,

  tag varchar2(50) not null,

  count number(10) not null,

  constraint"tbl_tag_tagid_pk"primary key(tagid)

)

 Partition by hash ( tagid)

Partition p1,

Partition p2 分成2分分区

复合分区:根据 hirdate创建范围分区,共创建三个分区,让这些分区在根据 tagid创建自分区。

create tabletbl_tag

( tagidnumber(10) not null,

  name varchar2(50) not null,

  hirdate date

)

partition byhash ( hirdate)

subpartition byhash ( tagid)

subpartition 2

(

 partition tag_p1 values less than (to_date(‘01’,’YYYYMMDD’)),

  partition tag_p2 values less than (to_date(‘02’,’YYYYMMDD’)),

 partition tag_p3 values less than (maxvalue)

);

列表分区:

 create table tbl_tag

( tagidnumber(10) not null,

  name varchar2(50) not null,

  add varchar2(50)

)

partition bylist (add)

(

partition tag_p1values (‘北京’),

partition tag_p2values (‘上海’,’天津’),

partition tag_p3values (default)

)

按地区分为 北京,  上海和天津  如果输入前面分区没有的值,则存入p3分区。

关于分区表的维护

添加分区:

Alert table 表 add partition 分区 values lessthan (400);

删除分区:

alert table 表 drop partition 分区;

截断分区,将删除表分区中的所有记录:

alert table 表 truncate partition 分区;

合并分区:

alert table 表  merge  partitions p1,p2 into partitionp2;

拆分分区:

alter table tbl_tag

 split partition tag_p2 at(2000)

 into(partition tag_p4,partition tag_p5);

 

alter table tbl_tag rename partition tag_p4to tag_p2;

alter table tbl_tag rename partition tag_p3to tag_p4;

alter table tbl_tag rename partition tag_p5to tag_p3;

猜你喜欢

转载自blog.csdn.net/qq_39145189/article/details/79781751