【问题标题】:Firebird: Why does ALTER TRIGGER have no effect on other sessions/connections?Firebird:为什么 ALTER TRIGGER 对其他会话/连接没有影响?
【发布时间】:2014-07-02 18:06:45
【问题描述】:
当我使用 FlameRobin SQL 编辑器修改触发器时,更改对其他会话/连接没有影响:触发器仍在执行旧版本。
这怎么可能?如何强制更改影响所有连接?
我确实在ALTER TRIGGER 之后调用了COMMIT,并且另一个连接中也没有打开的事务。这与事务无关,但与会话/连接有关。
“其他连接”是 Delphi 应用程序(使用 InterBase 组件),但可以使用两个 FlameRobin 实例重现完全相同的行为。
我正在使用:
- 火鸟 2.5.2(超经典)
- FlameRobin 0.9.3
- Delphi XE5 更新2
【问题讨论】:
标签:
session
triggers
database-connection
firebird
flamerobin
【解决方案1】:
在 Firebird 中,DDL 是事务性的,因此在您的事务更改数据库之前在开始的事务将看到数据库的状态,就像您的事务工作之前一样,只有在一个事务之后提交的数据库将能够看到您的更改。
除此之外,还有一个元数据缓存。在 Classic 和 SuperClassic 模型中,每个连接都有自己的缓存(而不是共享缓存),并且每个连接的缓存不会立即失效(虽然我不知道确切的细节)。这意味着在更改之前在事务中准备的语句将像数据库未更改一样工作(除非更改从根本上改变了表,否则此方法有效),而新准备的语句将与更改一起工作。
虽然在使用数据库时可以进行 DDL,但我建议对数据库脱机/单用户执行此操作,或者在执行 DDL 后强制用户重新连接,以确保所有连接都能看到并使用新的更改。
【解决方案2】:
就像 Mark Rotteveel 建议的那样,您必须在每次更改后重新启动所有内容。或者你有更好的选择:切换到 SuperServer,它的 bug 和内存泄漏也比 SuperClassic 少。超经典是垃圾。