oracle 锁-悲观锁与乐观锁

 

总结于ocl编程艺术:

 

经常发生的错误错误:更新丢失,旧数据更新了最新的数据。

 

解决问题的方法:

Oracle中看好悲观锁(取决于oracle锁开销小,高并发),但在其他的数据库已Deprecated

悲观锁:在用户有意执行更新等DML操作之前,就在行上加锁 for update nowait

悲观锁的结果:

                        给数据加锁,其他用户可以访问,但是不可以修改记录

                        当其他用户正在更新,则会得到ora-00054resource 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;

你可能感兴趣的:(oracle,锁,悲观锁,乐观锁)