9楼:你说的情况,即使用 lock table a表 in...这个语句也是没有解决的。 不信你试试:session A: -------------------- sql>truncate table a; --现在A表没有数据了 sql>lock table a in row exclusive mode nowait; sql>insert into a select * from b表 where b.callid= 1; --用1来做测试 sql>--现在不commit;session B: ------------------------------- sql>lock table a in row exclusive mode nowait; sql>insert into a select * from b表 where b.callid= 1; --用1来做测试这之后sessionA 做commit; session B再做commit; 现在A表的callid重复了吧?
由于oracle里面读不影响写,所以共享锁就没有意义了
v_sql := 'Insert into A表 select * from b表 where b.callid= v_callid' ;
我目前是这样用的.
v_locksql :='LOCK TABLE A表 IN ROW EXCLUSIVE MODE NOWAIT';
execute immediate v_locksql; --加行锁
execute immediate v_sql;
commit; --解锁
select * from t for update;
如果你做了事务的话,只要不commit就自动加锁了啊
这个sql是锁住A表,不让其他用户修改(但是读还是可以的)你的: Insert into A表 select * from b表 where b.callid= v_callid
这些插入的数据还没commit, 别人不可能访问到的。除了有主键索引方面的锁外,这些数据不存在锁的问题
我这里如果不把A表用行锁锁住的话(行锁用不同的callid为ID,加锁)就可能同时在A表中存在多条callid相同的记录,这是我不想看到的.
如果把A表中的callid建为主键,则多线程往A表中插入新记录时就会发生死锁.目前暂时没有好的办法解决.
不信你试试:session A:
--------------------
sql>truncate table a; --现在A表没有数据了
sql>lock table a in row exclusive mode nowait;
sql>insert into a select * from b表 where b.callid= 1; --用1来做测试
sql>--现在不commit;session B:
-------------------------------
sql>lock table a in row exclusive mode nowait;
sql>insert into a select * from b表 where b.callid= 1; --用1来做测试这之后sessionA 做commit; session B再做commit;
现在A表的callid重复了吧?
我看不会死锁,而是会阻塞。 后面插入的同样callid的线程在commit时会报错,这时rollback就好
dbms_lock.allocate_unique
dmbs_lock.request