每天在大型Oracle生产数据库(10g)上工作,我们注意到像
这样的操作锁定该表,并使所有持有该游标的游标无效。
如果表格很大(> 2000万行)且许多用户正在使用它,这会产生巨大的后果。
我的问题是:为什么Oracle会锁定表格(毕竟我们并没有改变它的结构,只是让用户有权阅读它)以及为什么它需要使游标无效?
有没有办法让那些“更柔和”的行动?
提前致谢。
备选问题:有没有办法知道在特定表上打开了多少游标,以便最大限度地减少失效对该对象的影响?
答案 0 :(得分:2)
可能一次授予群组权限,然后在将来授予用户成员权限,而不是直接表权限。我知道很简单的答案,但我得到的印象是你知道你在做什么,并且可以弄清楚细节。
答案 1 :(得分:2)
根据拨款消除失效:
创建xxx_READONLY角色,其中xxx是一些具有适当意义的值,并授予对角色的所有适当表的select访问权限,并在需要时将角色添加到用户。
根据触发器创建消除DDL锁:
上次我真的检查过,触发器是解释代码,而程序和包是编译代码。因此,通常不赞成在触发器中执行复杂的逻辑。可以在触发器中调用过程或包方法,并将触发器逻辑封装在过程/包中可以减轻或消除对基表的DDL锁定。
答案 2 :(得分:1)
我可以看到添加触发器如何需要锁定并使游标无效或等待所有打开的游标关闭,至少如果游标可能用于需要执行新触发器的操作。
很难看出为什么授予读取权限会有类似的要求,这可能只是实现的副作用。 MJB的答案似乎是处理这个问题的一种不错的方式(在很多情况下,无论如何都是一种很好的做法,简化了访问权限的管理)。
答案 3 :(得分:1)
答案 4 :(得分:0)
来自MJB的团队事务将是授予问题的最佳工作,对于“触发”问题,我建议将业务逻辑分离,以便它执行任何神奇的“触发器”将执行的操作,尤其是在20 mil + row table。
答案 5 :(得分:0)
1)我的问题是授予对表的读访问权限,这就是为什么你直接向表授予读权而不创建角色,授予对表的角色读取,然后向用户授予(或删除)角色的原因?这将删除授权上的锁定表问题。
2)Oracle会在创建触发器时锁定表,因为触发器可以在安装时更改表。所有DDL都将锁定表,创建一个事务,以确切知道它何时可以触发(或其他更改)。我怀疑赠款也是如此。
如果您不断地从表中添加/删除触发器,我将从触发器中删除您正在更改的代码并将其放入单独的PL / SQL过程中。然后根据需要更新过程。这将导致触发器变为无效(并需要重新编译),这是自动完成的。
我确定有一种方法可以使用Oracle数据字典中的v $视图找出针对给定表打开的游标。