rowid、ora_rowscn都是oracle表中的伪列。
一、rowid
rowid记录的是该行的物理位置,所以查询速度上比索引还要快。它的值绝对不会重复。
rowid的组成:
数据对象编号 文件编号 块编号 行编号
OOOOOO FFF BBBBBB RRR
二、ora_rowscn
表示每条记录所在块的最后一次修改时间。在同一块中,所有记录的ora_rowscn值是一样的,而且只要有一条记录修改后,该块内所有记录的ora_rowscn都会改变。
select ora_rowscn, empno from emp;
ORA_ROWSCNEMPNO
---------- ----------
7948156 1
8074042 101
8110067 7369
8110067 7499
8110067 7521
8110067 7566
8110067 7654
8110067 7698
8110067 7782
8110067 7788
8110067 7839
8110067 7844
8110067 7876
8110067 7900
8110067 7902
8110067 7934
8110067 9527
8110067 98
8110067 99
8110067 102
update emp set empno = 103 where empno = 102;
select ora_rowscn, empno from emp;
ORA_ROWSCNEMPNO
---------- ----------
7948156 1
8074042 101
8110343 7369
8110343 7499
8110343 7521
8110343 7566
8110343 7654
8110343 7698
8110343 7782
8110343 7788
8110343 7839
8110343 7844
8110343 7876
8110343 7900
8110343 7902
8110343 7934
8110343 9527
8110343 98
8110343 99
8110343 103
和empno为103的记录所在位置同一块中的其它记录,ora_rowscn都从8110067变为8110343。
默认的情况下,每个块中所有的记录的ora_rowscn都是相同的,当块中任意一条记录发生改变的情况下,块中所有记录的ora_rowscn都会变化为最新值,ora_rowscn的最小粒度是块。
rowid和ora_rowscn有什么用?
可以用来delete和update记录。
DELETE FROM EMP WHERE ROWID = 'AAAFl4AAEAAAAFvAAP' AND ORA_ROWSCN = '7789900';
UPDATE EMP SET HIREDATE = TO_DATE('1986-01-01 02:00:00', 'YYYY-MM-DD HH24:MI:SS') WHERE ROWID = 'AAAFl4AAEAAAAFvAAR' AND ORA_ROWSCN = '7790135';
1、在一个没有主键的表中可以使用rowid来删除一条记录。
2、使用ora_rowscn来实现乐观锁。要打开行级的ora_rowscn,默认是块级的。
三、乐观锁和悲观锁
悲观锁就是使用select … for update加锁,在更新前加锁,使得记录只能由一个事务修改。事务退出时释放锁。
乐观锁就是通过一个时间戳,先select获取时间戳,update时判断时间戳是否和取记录时的一样,即记录未被修改过。