我创建了一个这样的测试过程:
CREATE OR ALTER PROCEDURE tmp_fab
RETURNS (dummy INTEGER) AS
BEGIN
dummy = 1;
suspend;
END然后,第一个客户机(“客户端A")通过执行以下SQL来使用该过程:
SELECT *
FROM tmp_fab如果另一个客户端(“客户端B")试图更改过程(而”客户端A“事务仍然处于活动状态,没有提交/回滚),我将看到基于”客户端B“连接到数据库的方式的不同行为。
例如,:
试图按以下方式修改程序:
CREATE OR ALTER PROCEDURE tmp_fab
RETURNS (dummy INTEGER) AS
BEGIN
dummy = 2;
suspend;
END在提交“客户B”交易时..。
失败,但有以下错误:
Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
Lock conflict on no wait transaction.
Unsuccessful metadata update.
Object PROCEDURE "TMP_FAB" is in use.它成功了,正确地改变了程序.
这两种不同行为的原因是什么?(也许是一些事务设置?)
发布于 2022-09-07 21:44:51
是的,这是事务设置的问题。准确地说,错误消息中提到的“不等待”选项。此选项不在默认集合中,因此命名的客户端应用程序/组件必须显式地设置它。
通常,当遇到锁定的元数据对象时,“等待”事务会向其他事务/连接/服务器实例发送信号,以检查它们是否仍然活着,并礼貌地请求释放锁。然后它自然地等待锁被释放。“不等待”事务不会立即返回错误。
发布于 2022-09-07 20:16:41
在Firebird中没有元数据(如存储过程)的版本控制。因此,另一个连接正在使用的更新过程是有风险的操作,结果无法预测。作为经验法则,安排一些维护时间,并且只在垄断连接范围内改变数据库结构。
https://stackoverflow.com/questions/73638885
复制相似问题