总结于ocl编程艺术:
经常发生的错误错误:更新丢失,旧数据更新了最新的数据。
解决问题的方法:
在Oracle中看好悲观锁(取决于oracle锁开销小,高并发),但在其他的数据库已Deprecated
悲观锁:在用户有意执行更新等DML操作之前,就在行上加锁 for update nowait
悲观锁的结果:
给数据加锁,其他用户可以访问,但是不可以修改记录
当其他用户正在更新,则会得到ora-00054:resource busy
得到0行,说明此列已经被修改,
代码:
scott@ORA10G> select empno, ename, sal
2 from emp
3 where empno = :empno
4 and ename = :ename
5 and sal = :sal
6 for update nowait
7 /
EMPNO ENAME SAL
---------- ---------- ----------
7934 MILLER 1300
scott@ORA10G> update emp
2 set ename = :ename, sal = :sal
3 where empno = :empno;
1 row updated.
scott@ORA10G> commit;
乐观锁:
1只在更新的时候,保存着所有旧的值,用所有旧的值去查找记录来更新
乐观锁的结果:
成功更新数据
更新0条数据,说明更新的数据已经被更新了,需要添加附加的解决冲突的策略
代码:
Update table
Set column1 = :new_column1, column2 = :new_column2, ....
Where primary_key = :primary_key
And column1 = :old_column1
And column2 = :old_column2
2为表添加一列,当更新时,列值相同可执行更新,若不同则更新过时,添加解决冲突策略。一般使用trigger来维护这一列的值,在update时,更新这一列值。但是出发器的开销太大,为了实现这样的功能小用牛刀。
3使用校验和的乐观锁定:
(单向散列函数取一个变长输入串(即数据),并把它转换为一个定长的输出串(通常更小),这个输出称为散列值(hash value)。散列值充当输入数据的一个惟一标识符(就像指纹一样)。可以使用散列值来验证数据是否被修改)
实现方法:
OWA_OPT_LOCK.CHECKSUM
DBMS_OBFUSCATION_TOOLKIT.MD5
DBMS_CRYPTO.HASH
这种方面消耗cpu较多,但是网络传输量小。
4ORA_ROWSCN的乐观锁定
Ora
Ora_rowscn默认是块级的,要设置支持行
create table dept
(deptno, dname, loc, data,
constraint dept_pk primary key(deptno)
)
ROWDEPENDENCIES
as
select deptno, dname, loc, rpad('*',3500,'*')
from scott.dept;