【问题标题】:Microsoft AlwaysOn failover solution and DelphiMicrosoft AlwaysOn 故障转移解决方案和 Delphi
【发布时间】:2015-05-27 10:12:21
【问题描述】:

我正在尝试使 Delphi 应用程序与 AlwaysOn 解决方案一起使用。我在谷歌上发现我必须在连接字符串中使用MultiSubnetFailover=True

应用程序在 Delphi XE3 中编译并使用TADOConnection

如果我在连接字符串中使用Provider=SQLOLEDB,应用程序会启动,但看起来MultiSubnetFailover=True 无效。

如果我使用Provider=SQLNCLI11(我在 Google 上发现 OLEDB 不支持 AlwaysOn 解决方案,我必须使用 SQL Native 客户端)我在尝试打开连接时得到无效属性。

连接字符串是:

Provider=SQLOLEDB.1;Password="password here";Persist Security Info=True;User ID=sa;Initial Catalog="DB here";Data Source="SQL Instance here";MultiSubnetFailover=True

我是否必须在 Delphi 上升级到较新版本才能使用此故障转移解决方案,还是连接字符串中缺少某些内容?

【问题讨论】:

  • 您在连接字符串中写了SQLOLEDB.1,但前面提到您需要使用本机客户端SQLNCLI11 作为Provider 是不是错字?这可以解释无效属性错误...
  • 你是对的。似乎不支持OLEDB,所以必须使用SQL Native Client,它的连接字符串语法不同(connectionstrings.com/…)。

标签: delphi delphi-xe3 alwayson adoconnection


【解决方案1】:

我目前正在将 XE2 与 SQL Server AlwaysOn 一起使用。如果您阅读文档,您会发现 AlwaysOn 弹性事件会导致您的数据库连接失败,您需要启动一个新连接。

如果 SqlClient 应用程序连接到 AlwaysOn 数据库, 故障转移,原始连接断开,应用程序必须 在故障转移后打开一个新连接以继续工作。

我已经通过使用我自己的版本覆盖 TAdoQuery 组件的简单权宜之计解决了这个问题,该版本在连接失败后重试连接。这可能不是正确的方法,但它确实有效。它所做的是覆盖为打开而调用的方法(如果查询返回结果集)或执行 SQL(否则),如果由于连接丢失错误而失败,则再次尝试(但仅一次)。我已经针对 AlwaysOn 切换进行了大量测试,它对我们的配置工作可靠。它还将对任何其他连接丢失事件做出反应,从而处理导致查询失败的其他一些原因。如果您使用的是 TAdoQuery 以外的组件,则需要为该组件创建类似的覆盖。

这可能可以通过其他方式处理,但是一旦我发现可行的方法,我就停止寻找替代方案。您可能需要整理使用声明,因为它清楚地包含了一些不需要的东西。 (仅仅看这段代码就想离开并重构代码重复)

unit sptADOQuery;

interface

uses
  Windows, Messages, SysUtils, Classes, Db, ADODB;

type
  TsptADOQuery = class(TADOQuery)
  protected
    procedure SetActive(Value: Boolean); override;
  public
    function ExecSQL: Integer;   // static override
  published
  end;

procedure Register;

implementation

uses ComObj;

procedure Register;
begin
  RegisterComponents('dbGo', [TsptADOQuery]);
end;

procedure TsptADOQuery.SetActive(Value: Boolean);
begin
  try
    inherited SetActive(Value);
  except
    on e: EOleException do
    begin
      if (EOleException(e).ErrorCode = HRESULT($80004005)) then
      begin
        if Assigned(Connection) then
        begin
          Connection.Close;
          Connection.Open;
        end;
        inherited SetActive(Value);   // try again
      end
      else raise;
    end
    else raise;
  end;
end;

function TsptADOQuery.ExecSQL: Integer;
begin
  try
    Result := inherited ExecSQL;
  except
    on e: EOleException do
    begin
      if (EOleException(e).ErrorCode = HRESULT($80004005)) then
      begin
        if Assigned(Connection) then
        begin
          Connection.Close;
          Connection.Open;
        end;
        Result := inherited ExecSQL;   // try again
      end
      else raise;
    end
    else raise;
  end;
end;

end.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 2019-09-28
    • 1970-01-01
    • 2010-11-06
    相关资源
    最近更新 更多