加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Microsoft AlwaysOn故障转移解决方案和Delphi

发布时间:2020-12-14 01:57:20 所属栏目:Windows 来源:网络整理
导读:我正在尝试使用Delphi应用程序来使用AlwaysOn解决方案.我在Google上发现我必须在连接字符串中使用MultiSubnetFailover = True. 应用程序在Delphi XE3中编译并使用TADOConnection. 如果我在连接字符串中使用Provider = SQLOLEDB,则应用程序启动但看起来像Mult
我正在尝试使用Delphi应用程序来使用AlwaysOn解决方案.我在Google上发现我必须在连接字符串中使用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上的较新版本才能使用此故障转移解决方案,或者我是否在连接字符串中缺少某些内容?

解决方法

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

If a SqlClient application is connected to an AlwaysOn database that
fails over,the original connection is broken and the application must
open a new connection to continue work after the failover.

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

有可能这可以通过其他方式处理,但是一旦我找到了有效的方法,我就不再寻找替代方案了.您可能希望整理use语句,因为它清楚地包含了一些不需要的东西. (只看这段代码让我想要离开并重构代码重复)

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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读