在oracle中,我有一个表EMPLOYEE(EMPID,EMPNAME)
表,EMPID
上有主键。
两位用户拥有此表格的插入权限,例如USER1
和USER2
。
User1
插入EMPID=1 and EMPNAME='XYZ'
的记录但未提交。但是如果USER2
尝试插入相同的记录EMPID=1 and EMPNAME='XYZ'
,则屏幕会挂起,直到user1
提交或回滚。
是否有选项可以让没有任何挂起的用户插入此记录,并且提交第二个的用户应该得到PK违规错误。
谢谢, Niju Jose
答案 0 :(得分:0)
在单用户数据库中,用户可以修改数据库中的数据,而无需担心其他用户同时修改相同的数据。但是,在多用户数据库中,多个并发事务中的语句可以更新相同的数据。同时执行的交易需要产生有意义且一致的结果。
Isolation Level Dirty Read Nonrepeatable Read Phantom Read
---------------- ------------ ------------------ -------------
Read uncommitted Possible Possible Possible
Read committed Not possible Possible Possible
Repeatable read Not possible Not possible Possible
Serializable Not possible Not possible Not possible
在您的情况下,Oracle获取行级锁定。插入案例更简单,因为插入的行被锁定,但其他用户也看不到它们,因为它们未被提交。当用户提交时,他也会释放锁,因此,其他用户可以查看这些行,更新它们或删除它们。
阅读有关数据并发性和一致性的here。 另请参阅Insert Mechanism
的更多详细信息为了解释更多,我在这里重现Florin's回答
例如,设为tableA(col1编号,col2编号),其中包含此数据:
col1 | col2
1 | 10
2 | 20
3 | 30
如果用户John在time1
处发布:
update tableA set col2=11 where col1=1;
将锁定row1。
在time2
用户标记处发出
update tableA set col2=22 where col1=2;
更新将起作用,因为第2行未锁定。
现在该表在数据库中查找:
col1 | col2
1 | 11 --locked by john
2 | 22 --locked by mark
3 | 30
对于Mark表是(他没有看到未经修改的变化)
col1 | col2
1 | 10
2 | 22
3 | 30
对于John表是:(他没有看到未经修改的变化)
col1 | col2
1 | 11
2 | 20
3 | 30
如果标记尝试time3
:
update tableA set col2=12 where col1=1;
当John发出time4
时,他的会话将一直持续到commit
。(回滚也会解锁行,但更改将会丢失)
表是(在db中,在时间4):
col1 | col2
1 | 11
2 | 22 --locked by mark
3 | 30
Immediatley,在John的提交之后,row1被解锁并且标记的更新将完成这项工作:
col1 | col2
1 | 12 --locked by mark
2 | 22 --locked by mark
3 | 30
让我们在time5标记一个rollbak:
col1 | col2
1 | 11
2 | 20
3 | 30
因此,您的挂起是由于Oracle引擎在向user2发出明确响应之前等待User1的提交或回滚这一事实。