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

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

如果我在连接字符串中使用Provider=SQLOLEDB,则应用程序启动,但MultiSubnetFailover=True似乎无效。

如果我使用Provider=SQLNCLI11(我在Google上发现OLEDB不支持AlwaysOn解决方案,并且必须使用SQL Native Client),则在尝试打开连接时会获得无效的属性。

连接字符串为:

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上升级到较新版本才能使用此故障转移解决方案,或者连接字符串中缺少某些内容?

最佳答案

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



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

可能可以通过其他方式处理此问题,但是一旦发现有效的方法,我便停止寻找替代方法。您可能想要整理一下uses语句,因为它显然包含了一些不需要的东西。 (只是看这段代码,我也想离开并重构代码重复项)

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.

关于delphi - Microsoft AlwaysOn故障转移解决方案和Delphi,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30479459/

10-09 07:13