简体   繁体   English

存储过程将新记录转移到链接服务器的连接断开

[英]Stored procedure transferring new records to linked server losing connection

Let me preface this by saying I am not a sql expert. 首先,我不是SQL专家,以此作为我的序言。 Thanks in advance for reviewing my question. 在此先感谢您审核我的问题。

I am having some trouble with a stored procedure that periodically loses it's connection to a linked server in the middle of transferring new records to a table there (a lot of records). 在将新记录传输到那里的表(很多记录)的过程中,存储过程会定期失去与链接服务器的连接,这给我带来了麻烦。 I'm wondering about some things. 我想知道一些事情。

First, is there a better way to complete the task that is faster and more efficient? 首先,是否有更好的方法来完成更快,更高效的任务?

And second, is there a way to better handle the loss of connection attempting to re-try the previous step in an effort to continue where it left off, possibly after waiting 15 or so minutes in case there is some temporary disconnect with the linked server (that may last more than what is allowed before terminating)? 其次,是否有一种方法可以更好地处理连接丢失的问题,尝试重新尝试上一步,以尝试从上次中断的位置继续进行,可能需要等待15分钟左右,以防与链接服务器之间的某些临时断开连接(可能会比终止之前允许的持续时间更长)?

Also I'm curious, when something like the highlighted step takes place, if the sql is being executed against the linked server, and the connection is lost, does sql attempt to reconnect and continue for a timeout period or since this is a compare statement does it just break? 我也很好奇,当发生诸如突出显示的步骤之类的事情时,如果正在对链接服务器执行sql,并且连接丢失了,sql是否会尝试重新连接并继续超时,或者这是一个compare语句它会破裂吗? I don't really understand how it works. 我不太了解它是如何工作的。

Here is the section where connection loss is most common, usually occurring in the first insert statement (first step within begin catch block): 这是连接丢失最常见的部分,通常在第一个insert语句(begin catch块中的第一步)中发生:

UPDATE [LINKEDSERVER.XYZ.COM].dest_database1.dbo.run
  SET last_result = 32
  WHERE type = 158;

BEGIN TRY
    INSERT INTO [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table1 ( CID , BID , Question1 , Question2 , Question3 , Question4 , Question5 , Question6 , Question7 , Question8 , Question9 , Question10 , Comments , EmailAddress , Name , Address , Address2 , City , State , Zip ) 
    SELECT src.CID , src.BID , src.Question1 , src.Question2 , src.Question3 , src.Question4 , src.Question5 , src.Question6 , src.Question7 , src.Question8 , src.Question9 , src.Question10 , src.Comments , src.EmailAddress , src.Name , src.Address , src.Address2 , src.City , src.State , src.Zip 
      FROM table1 AS src LEFT OUTER JOIN [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table1 AS dst ON src.CID = dst.CID AND src.BID = dst.BID
      WHERE dst.CID IS NULL;

    INSERT INTO [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table2 ( CID , AccountNumber , Name , Address , Address2 , City , State , Zip , BShort, EmailAddress ) 
    SELECT src.CID , src.AccountNumber , src.Name , src.Address , src.Address2 , src.City , src.State , src.Zip , src.BShort, src.EmailAddress 
      FROM table2 AS src LEFT OUTER JOIN [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table2 AS dst ON src.BShort = dst.BShort
      WHERE dst.BShort IS NULL;
END TRY
BEGIN CATCH
    SELECT @ErrorCode = @@Error;
    SELECT @ErrorResult = 109;
    SELECT @ErrorMessage = 'Failed Copy ' + CAST ( @ErrorCode AS varchar ) ;
    GOTO ExitWithError;
END CATCH;

INSERT INTO [LINKEDSERVER.XYZ.COM].dest_database1.dbo.system_log ( notes , log_type , source_type , parent_id ) 
VALUES ( 'Copied tables xyz ' , 45 , 58 , 0 ) ;

UPDATE [LINKEDSERVER.XYZ.COM].dest_database1.dbo.run
  SET last_result = 31
  WHERE type = 158;

I understand that if the connection is lost, my catch block doesn't execute, so ExitWithError isn't used. 我知道,如果连接丢失,则不会执行catch块,因此不会使用ExitWithError。 And I think I understand when the connection is lost, a rollback occurs (not sure how/if this works with linked servers because some of the records are transferred when this happens), and it just quits executing everything - because neither the catch is executed or the statements after the entire begin catch block. 而且我想我知道当连接丢失时,会发生回滚(不知道如何/是否与链接服务器一起工作,因为发生这种情况时会传输某些记录),并且它只是退出执行所有操作-因为没有执行catch或整个begin catch块之后的语句。 I was hoping to, in the event this occurs, log something so that the stored procedure, when it runs again (set to run every 30 min until successful), it can pick up where it left off, because I have code in the beginning that looks for the last status/log entries and determines what to do. 我希望在发生这种情况时记录一些信息,以便存储过程再次运行时(设置为每30分钟运行一次,直到成功),它可以从中断的地方开始,因为我的代码开头查找最后的状态/日志条目并确定要执行的操作。 Is there a better way to handle this? 有没有更好的方法来解决这个问题?

So first tip, Do the stored procedure from the other server (destination) if you can. 因此,第一个技巧是,如果可以,请从其他服务器(目标)执行存储过程。 In other words switch the local and the linked server. 换句话说,切换本地服务器和链接服务器。 The reason is I have had significantly improved performance to a DML (insert/update/delete) command from a Linked Server to a local table. 原因是我已大大改善了从链接服务器到本地表的DML(插入/更新/删除)命令的性能。 When doing the DML into a linked table the performance stinks! 将DML制作到链接表时,性能很差!

Next effectively use the ids, are they sequential? 接下来有效使用ID,它们是顺序的吗? Can you just take the MAX of what is at the destination server instead of having to Join large tables between the servers? 您能否仅使用目标服务器上的最大值,而不必在服务器之间加入大型表?

If you cannot count on sequential then you can build a temp table on the source server and filter there instead of trying to do it across tables. 如果您不能依靠顺序,则可以在源服务器上构建一个临时表并在其中进行过滤,而不是尝试跨表进行操作。 If just ids you can also try to pass XML in nvarchar format back and forth. 如果只是id,您还可以尝试来回传递nvarchar格式的XML。 Or you can maintain a tracking table on the source so you know what ids have already been processed using the OUTPUT inserted.id INTO .... from your insert statement. 或者,您可以在源上维护一个跟踪表,以使您知道使用插入语句中的OUTPUT insert.id INTO ....已经处理了哪些ID。

Finally set your procedure to batch/cut up and do the transactions in smaller chunks such as SELECT TOP x# of records at a time. 最后,将过程设置为批处理/分批处理,并以较小的块(例如一次SELECT TOP x#个记录)进行事务。 You can still place the whole thing in a while loop so that it does it all in one execution of the proc, but then you can do your transactions in smaller more manageable pieces. 您仍然可以将整个事情放在while循环中,这样就可以在proc的一次执行中完成所有工作,但是随后您可以以更小,更易于管理的方式进行事务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM