Welcome 微信登录

首页 / 软件开发 / JAVA / 在JAVA端使Oracle存储过程串行地执行

在JAVA端使Oracle存储过程串行地执行2011-07-28我们知道给资源上锁可以使我们串行化地访问资源,oracle为plsql开发人员提供了DBMS_SQL包用来管理USERL LOCK锁资源。这种锁可以使得多个session串行的执行某个存储过程,还可以用来排他的访问某个外部设备或服务,甚至可以检测事务的提交或回滚(提交或回滚时锁的释放)。

有人说我在java端调用db的存储过程,可以使用synchronized lock来串行的调用存储过程。那就不需要db lock呢?因为当java端应用服务器down的时候,存储过程已经在执行了,但是可能oracle session(RAC的db)并没有立即释放掉。当我们重启应用服务器后,其实后台的以前的存储过程还在执行,如果再次调用存储过程,这就无法保证存储过程的串行执行了。所以说存储过程的同步锁是必须放在Oracle db端的。

DBMS_LOCK包具有下面几个API,主要说明以下几个,其他的可以参考oracle相应文档,我们这里只用X锁(排他锁也称写锁)。

PROCEDURE DBMS_LOCK.ALLOCATE_UNIQUE
(lockname IN VARCHAR2
,lockhandle OUT VARCHAR2
,expiration_secs IN INTEGER DEFAULT 864000);

参数描述
lockname锁的名称
lockhandle与该名称相对应的锁的唯一标识
expiration_secs这种名称到锁的映射的保存时间
当多个session用同样的名字lockname来获取唯一标识字符串时,不同的session用同样名字获取的lockhandle是相同的,lockname是最大128位的字符串,而且是大小写敏感的,锁的名字最好不要用"ORA$"打头,这种锁的名称是被oracle保留的名称。DBMS_LOCK.ALLOCATE_UNIQUE执行完后就会commit所以不能被trigger调用。所有获得的映射都为存放在SYS用户DBMS_LOCK_ALLOCATED视图中。

FUNCTION DBMS_LOCK.REQUEST
(id IN INTEGER
,lockmode IN INTEGER DEFAULT X_MODE
,timeout IN INTEGER DEFAULT MAXWAIT
,release_on_commit IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;
FUNCTION DBMS_LOCK.REQUEST
(lockhandle IN VARCHAR2
,lockmode IN INTEGER DEFAULT X_MODE
,timeout IN INTEGER DEFAULT MAXWAIT
,release_on_commit IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;

参数描述
id锁的唯一标识
lockhandle由DBMS_LOCK.ALLOCATE_UNIQUE返回的handle
lockmode锁的模式
timeout等待时间
release_on_commitCOMMIT or ROLLBACK事务时是否释放锁
返回值描述
0成功申请到锁
1超时
2死锁
3参数错误
4已经拥有特定id或handle的锁
5不合法的lockhandle