In una SP di inserimento di un nuovo record, ottengo alcuni valori
eseguendo una procedura su un linked server, che ᅵ in realtᅵ un DB/2 su
AS400.
A causa di una serie di problemi di sistema, il DTC va spesso in crash.
Quando ciᅵ avviene, l'EXEC sul linked server resta appeso, nel senso
che posso lasciarlo lᅵ anche due giorni che non si completa mai.
Ad un certo punto l'Execute invocato dal client va in timeout, ad
esempio 30", e avviene l'errore lato client.
Vorrei invece ottenere una situazione per cui, in caso di freeze
dell'EXEC sul linked server, dopo un tempo X l'Exec stesso vada in
errore, consentendomi di gestire la situazione (ad esempio inserendo
dei valori di default e avvisando l'utente di avvisare il CED e di
sistemarli piᅵ tardi).
L'ideale sarebbe in realtᅵ di poter leggere il timeout dell'Execute
invocato dal client (client e tecnologie diverse possono usare timeout
diversi), e assegnare all'Exec interno alla SP un timeout leggermente
inferiore, in modo che l'errore interno alla SP sia gestibile prima che
vada in timeout il client.
Non trovo perᅵ alcun modo di impostare un timeout per un comando EXEC
AT.
Riporto qui sotto un estratto della SP, l'EXEC incriminato ᅵ poco oltre
la metᅵ del codice.
--PROCEDURA DI INSERIMENTO NUOVO ELEMENTO
ALTER PROCEDURE DBO.SP_INSERT_CAMPIONE
@COD_RECORD NVARCHAR(20)
, @DESC_RECORD NVARCHAR(255) = ''
, @COD_ARTICOLO_ERP NVARCHAR(20) = ''
, @OPER varchar(25) = ''
, @TERM varchar(250) = ''
, @ERRORE VARCHAR(255) OUTPUT
WITH ENCRYPTION AS
SET NOCOUNT ON
DECLARE @RETVAL INTEGER
SET @RETVAL = 0
SET @ERRORE = 'Inserimento Riuscito.'
IF OBJECT_ID('tempdb.DBO.#RISULTATO') is not null
DROP TABLE DBO.#RISULTATO
CREATE TABLE DBO.#RISULTATO
(
DS_NOR_P NVARCHAR(9)
, DS_NOR_A NVARCHAR(9)
, DS_DATA DATETIME
, DS_COD8 NVARCHAR(8)
, DS_RETCODE NVARCHAR(1)
)
DECLARE @STRINGASQL NVARCHAR(2000)
SET @STRINGASQL = 'CALL QGPL.XPCGETLOT ('' + <PARAMETRI> + '')'
--QUESTO EXEC PUO' FALLIRE RESTANDO APPESO ALL'INFINITO
INSERT INTO DBO.#RISULTATO
EXEC ( @STRINGASQL
) AT AS400Server
--QUINDI NON ENTRO MAI QUI
IF @@ERROR <> 0 OR @@ROWCOUNT <> 1
BEGIN
SET @retVal = -12
SET @Errore =
'AS400 NON RISPONDE ALLA RICHIESTA DI DETTAGLI'
GOTO gestEnd
END
/*
operazioni di inserimento....
*/
gestEnd:
RETURN @RETVAL
Ciao
Alberto
Il concetto era sostanzialmente questo:
Una mia SP deve invocare una seconda SP (accidentalmente su un linked
server).
Io voglio che questa seconda SP termini entro un tempo brevissimo,
diciamo due secondi, oppure la mia SP gestirᅵ l'errore e proseguirᅵ la
propria esecuzione in una modalitᅵ opportuna.
Quindi, ho la necssitᅵ di impostare un timeout specifico per quel EXEC,
senza usare il timeout dell'exec invocato dal client.
Purtroppo non posso utilizzare il timeout delle proprietᅵ del linked
server perchᅵ altre operazioni devono invece durare molto piᅵ tempo
senza generare errori.
Tengo come ultima spiaggia la creazione di un secondo linked server,
clone del primo ma con un timeout basso, da usare per questa specifica
operazione.
Idee?
Alberto
Situazione sempre critica.
Altre informazioni, se qualcuno avesse voglia di studiare il caso:
- Lo spid che esegue la Insert Exec non 'muore'. Anche eseguendo KILL
123, poi con SP_WHO2 si legge KILLED/ROLLBACK all'infinito, anche dopo
ore.
- L'esecuzione del EXEC AT, se commento l'Insert che ci sta davanti,
esegue senza problemi.
- Il riavvio del MSDTC non porta benefici, anche se il System
Administrator di DB/2 mi dice che nel momento del riavvio si vede
'qualcosa' che appare e scompare nel job manager di AS400.
Alberto
> - Il riavvio del MSDTC non porta benefici, anche se il System
> Administrator di DB/2 mi dice che nel momento del riavvio si vede
> 'qualcosa' che appare e scompare nel job manager di AS400.
Non credo di poterti aiutare, ma visto che c'ᅵ di mezzo MSDTC, puoi
dirci che valore ha l'opzione 'remote proc transaction promotion' del
server collegato?
Se ᅵ impostata a 'true' e la imposti a 'false', il problema ᅵ comunque
presente?
--
David Martin
Guarda, ho cercato ovunque.
Nel linked server, nel provider (MSDASQL), nel DSN di sistema verso
DB/2.
Mi sono anche fatto generare gli script di Create del linked server da
SSMS.
Ho guardato tutte le Option di SP_ServerOption.
Ma quel "remote proc transaction promotion" proprio non l'ho trovato...
> Se ᅵ impostata a 'true' e la imposti a 'false', il problema ᅵ comunque
> presente?
Se la trovo, lo provo subito...
Cioᅵ, in realtᅵ la prova deve durare del tempo, perchᅵ il problema si
innesca randomicamente, non ᅵ una cosa deterministica.
Alberto
> Cioè, in realtà la prova deve durare del tempo, perchè il problema si
> innesca randomicamente, non è una cosa deterministica.
Hai provato questo ?
http://msdn.microsoft.com/en-us/library/ms177457%28SQL.90%29.aspx
Provato adesso.
Ho messo il timeout a 25 (25", appunto).
Poi, essendo in questo momento nella (s)fortunata condizione in cui non
funziona niente su questo linked server, ho eseguito un banale Exec At
(banale nel senso che in condizioni ok esegue in un paio di secondi),
ma l'esecuzione ᅵ rimasta lᅵ all'infinito.
Ho chiuso la finestra (anche il Kill non riusciva ad arrestare
l'esecuzione, in SP_Who2 restava in Killer/Rollback, anche se era una
semplice Select e non una Call) dopo una decina di minuti.
Ciao
Alberto
Sorpreso dal leggere quanto hai scritto, sono andato a vedere meglio e
ho notato che ᅵ un'opzione presente in SQL Server 2008 e non in SQL
Server 2005:
http://technet.microsoft.com/en-us/library/ms178532.aspx
--
David Martin
> Poi, essendo in questo momento nella (s)fortunata condizione in cui non
> funziona niente su questo linked server, ho eseguito un banale Exec At
> (banale nel senso che in condizioni ok esegue in un paio di secondi), ma
> l'esecuzione ᅵ rimasta lᅵ all'infinito.
Ci puoi dire con precisione quali driver e di quale versione sono stati
utilizzati per creare il linked server?
Tanto per dirne una, io riesco ora a usare i driver oledb forniti da
IBM, con il iSeries (Client) Access V5R3M0.
Con le versioni precedenti era un bagno di sangue e puntualmente dovevo
usare i driver odbc, ora invece riesco a scrivere direttamente in AS/400
usando i driver oledb.
--
David Martin
> Provato adesso.
Prova ad eseguire un exec ('WAITFOR DELAY ''00:00:20''') sul server
remoto dopo aver impostato il timeout a 15 secondi ... e vedi se va in
timeout
iSeries Access ODBC Driver 10.00.12.00 IBM Co. CWBODBC.DLL 12/06/2005
> Tanto per dirne una, io riesco ora a usare i driver oledb forniti da IBM, con
> il iSeries (Client) Access V5R3M0.
> Con le versioni precedenti era un bagno di sangue e puntualmente dovevo usare
> i driver odbc, ora invece riesco a scrivere direttamente in AS/400 usando i
> driver oledb.
Eh, invece a me dicevano esattamente il contrario, ossia che con gli
OleDb ᅵ un macello mentre con ODBC si va via lisci...
Alberto
Guarda, quel exec
exec ('WAITFOR DELAY ''00:00:20''') AT MyLinkedServer
ᅵ lᅵ che gira da qualche minuto, beatamente ignaro del timeout.
Allora mi sono chiesto: capisco che possa durare molto 'qualche cosa',
ma questo qui ᅵ un comando che dopo 20" DEVE finire.
Sempre che venga eseguito, perᅵ.
Allora ho lanciato questo qui sotto:
exec ('PROVA PIPPO E PLUTO') AT MyLinkedServer
e anche questo ᅵ in esecuzione da minuti.
Siamo quindi a questo punto: l'EXEC non riesce a AVVIARE l'esecuzione
sul linked server, e neppure a passare il comando (visto che qui non
viene neppure sollevata la logica eccezione)...
Reggo ancora un po', poi dovremo riavviare il server (cosa che risolve
fino alla piantata successiva), perchᅵ siamo in produzione e le cache
ricevute prima di questo 'freeze' stanno per scadere...
Alberto
I numeri sembrano corrispondere a quelli che uso io.
E la versione del Client Access qual'ᅵ? La vedi da Start > Programmi >
IBM Client Access > Proprietᅵ Client Access.
>> Tanto per dirne una, io riesco ora a usare i driver oledb forniti da
>> IBM, con il iSeries (Client) Access V5R3M0.
>> Con le versioni precedenti era un bagno di sangue e puntualmente
>> dovevo usare i driver odbc, ora invece riesco a scrivere direttamente
>> in AS/400 usando i driver oledb.
>
> Eh, invece a me dicevano esattamente il contrario, ossia che con gli
> OleDb ᅵ un macello mentre con ODBC si va via lisci...
E' quello che intendevo dire: con odbc ᅵ tutto ok da una vita, oledb non
ᅵ mai funzionato.
Io perᅵ dal Client Access V5R3 riesco ad usare con successo anche i
Altro tentativo: il linked server ᅵ stato creato probabilmente partendo
da una origine dati odbc. Nell'origina dati odbc, vai a vedere la scheda
'Prestazioni', clicca su 'Avanzate' e prova a togliere la spunta
dall'opzione 'Consenti superotempo query'.
> Siamo quindi a questo punto: l'EXEC non riesce a AVVIARE l'esecuzione
> sul linked server, e neppure a passare il comando (visto che qui non
> viene neppure sollevata la logica eccezione)...
Se non erro, quell'istruzione deve inserire i dati si una select fatta
su AS/400 direttamente in una tabella temporanea. Non puoi usare i SSIS
per estrarre i dati?
--
David Martin
> Guarda, quel exec
> exec ('WAITFOR DELAY ''00:00:20''') AT MyLinkedServer
> è lì che gira da qualche minuto, beatamente ignaro del timeout.
> Allora mi sono chiesto: capisco che possa durare molto 'qualche cosa',
> ma questo qui è un comando che dopo 20" DEVE finire.
Pero' aspè, waitfor delay è sintassi di sql, il server remoto è db2 ?
Allora scusa forse è per quello che non va... (ma cmq dovrebbe darti
errore)
Ora sei nella situazione che l'istruzione "select pippo from tabella"
va liscio da console DB2 ma non va da sql via EXEC da server remoto ?
Riesci ad interrogare gli oggetti del linked server con il nome a 4
parti: select top 1 1 from linksedserver.db.dbo.table (o quale che sia
la sintassi di db2) ?
Se la risposta è si, allora potresti provare ad usare (sempre che ci
sia) la corrispondente sp_executesql di DB2, sempre che cambi
qualcosa ...
HTH
IBM iSeries Access per Windows
Versione 5 Release 3 Livello 0 Servizio SI30707
Alberto
>> E la versione del Client Access qual'ᅵ? La vedi da Start > Programmi >
>> IBM Client Access > Proprietᅵ Client Access.
>
> IBM iSeries Access per Windows
> Versione 5 Release 3 Livello 0 Servizio SI30707
E' identico a quello che uso io.
--
David Martin
> Tanto per dirne una, io riesco ora a usare i driver oledb forniti da
> IBM, con il iSeries (Client) Access V5R3M0.
> Con le versioni precedenti era un bagno di sangue e puntualmente dovevo
> usare i driver odbc, ora invece riesco a scrivere direttamente in AS/400
> usando i driver oledb.
Aggiornamento sulla situazione: i driver oledb del Client Access V5R3M0
funzionano, nel senso che permettono di scrivere direttamente su AS400
(iSeries) senza errori, ma hanno delle prestazioni che fanno schifo.
Sono dovuto tornare di corsa all'esecuzione di pacchetti dts all'interno
dei ssis, perchᅵ nei trasferimenti che faccio io, sono piᅵ veloci di
almeno 100 volte...
--
David Martin
> Aggiornamento sulla situazione: i driver oledb del Client Access V5R3M0
> funzionano, nel senso che permettono di scrivere direttamente su AS400
> (iSeries) senza errori, ma hanno delle prestazioni che fanno schifo.
E' l'aggiornamento della situazione dei driver o della situazione di
Albe ?
Un aggiornamento sull'uso dei driver...
--
David Martin
> Un aggiornamento sull'uso dei driver...
Chissà Albe se e come ha risolto ...
Non ho risolto.
L'ho aggirato usando un giro completamente diverso.
Ciao
Alberto
> L'ho aggirato [CUT]
Acc ... il famoso workaround :)
Letteralmente...
Il punto ᅵ che se invoco una SP di DB/2, il DTC vuole aprire una
transazione, non ci sono santi. E in questa cosa, resta appeso a vita
(perchᅵ, immagino io, DB/2 non ha alcuna intenzione di aprire una
transazione di cui non ha bisogno).
Il tutto nasceva dalla necessitᅵ di ottenere un codice a fronte di
informazioni inserite dal client. Cioᅵ, il client dice "qual'ᅵ il lotto
con cui ho prodotto l'articolo pippo nella variante pluto?", e questa
informazione ᅵ in un database di DB/2 di dimensioni spropositate e che
nemmeno lontanamente vogliamo sincronizzare su SqlServer.
Allora l'idea, che in linea di principio funziona ma ogni tanto si
impalla, era di eseguire una SP di DB/2, a cui passare come parametri
"pippo" e "pluto", e ricevere un record con il risultato della ricerca.
Non c'erano santi di aggirare questo freeze, estemporaneo, randomico e
senza spiegazione.
Ma per fortuna DB/2 offre, al contrario di SqlServer (almeno fino al
2005) le viste parametriche. Modificando la SP di DB/2 con una vista
parametrica, a cui viene passato "Pippo" e "Pluto" e questa vista si
popola con un solo record contenente appunto il risultato della
ricerca, e invocando non piᅵ un EXEC ma una SELECT sulla vista
parametrica, non abbiamo avuto piᅵ blocchi.
Ciao
Alberto
Ciao Albe,
Sarᅵ contento marc!! :-D
Non conosco le viste parametriche di DB2, ma SQL Server offre le UDF inline
che puoi considerare in tutto e per tutto viste parametriche :-)
Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo
http://social.microsoft.com/Forums/it-IT/sqlserverit
..mmm.. Ciao Albe, sei sicuro?
Intendi proprio che db2 ammette una sintassi del tipo:
create view(<Parameters>)
as
select ...
?
Non trovo documentazione a riguardo.
Se cosᅵ fosse potremmo forse sperare che anche ms si convinca che ᅵ
utile e ragionevole. Ma non mi pare...
> Alberto
marc.
Non ho la piᅵ pallida idea della sintassi di creazione vista in DB2,
c'ᅵ una persona che lavora lato DB2 e io lato SqlServer.
La sintassi che uso io (in un openquery su DB2) ᅵ:
SELECT * FROM table(QGPL.MyProcedure (<parametri>) AS X for read only
Adesso, dirti esattamente come funzioni quella cosa, ossia se sia una
sorta di Cast a Table del resultset di MyProcedure, o se sia una vista
vera e propria, non so dirtelo.
Il responsabile di DB2 la chiama Vista Parametrica.
Ciao
Alberto