Domanda

Ho lavorato su questo per circa un giorno e mezzo, e ha cercato numberous blog e articoli della guida sul Web.Ho trovato alcune domande in MODO correlati a questo errore, ma non pensavo che piuttosto applicato per la mia situazione (o, in alcuni casi, purtroppo, non riuscivo a capire abbastanza bene da implementare :P).Non sono certo io in grado di descrivere questo abbastanza bene per l'aiuto...ma qui va:

Abbiamo una .NET app per tenere traccia delle nostre risorse.C'è una funzione di esportazione di copiare una risorsa per il sistema di tracciamento in tempo e il sistema di fatturazione;questo accede a una stored procedure che si collega a tempo e fatturazione database.

Recentemente ho spostato il sistema di fatturazione del database su un nuovo server (server originale:Server 2003 SP2 di SQL 2005;nuovo server:Server 2008 R2, SQL 2008 R2).Ho un Server Collegato set up che punta al 2008 database.Ho aggiornato la stored procedure per il punto per il 2008 server, e poi ho avuto un errore di MSDTC e RPC (http://www.safnet.com/writing/tech/archives/2007/06/server_myserver.html).Ho abilitato 'rpc/rpc out' sul Server Collegato e impostato MSDTC per consentire l'Accesso alla Rete (qualcosa di simile a questo: http://www.sqlwebpedia.com/content/msdtc-troubleshooting).

Ora mi sto sopra, quando cerco di eseguire la funzione di esportazione:"Questo SqlTransaction ha completato;non è più utilizzabile." Quello che mi sembra strano è che quando mi basta eseguire la stored procedure (da SSMS), si dice che è stato completato con successo.

Qualcuno ha visto questo prima?Mi sono perso qualcosa nella configurazione?Io continuo sulle stesse pagine, e l'unica cosa che ho trovato è che non ho il riavvio dopo aver apportato le modifiche MSDTC (menzionato nel qui: http://social.msdn.microsoft.com/forums/en-US/adodotnetdataproviders/thread/7172223f-acbe-4472-8cdf-feec80fd2e64/).

Posso pubblicare una parte o tutte le stored procedure, se sarebbe d'aiuto...per favore fatemi sapere.

È stato utile?

Soluzione

Credo che questo messaggio di errore sia dovuto a una "transazione di zombi".

Cerca possibili aree in cui il Transacton viene impegnato due volte (o tornato indietro due volte, o rotolato indietro e impegnato, ecc.). Il codice .NET commette la transazione dopo che SP l'ha già impegnata? Il codice .NET lo ritorna quando si incontra un errore, quindi tenta di ripristinare di nuovo in una clausola di cattura (o infine)?

È possibile che una condizione di errore non sia mai stata colpita sul vecchio server, e quindi il codice "doppio rollback" difettoso non è mai stato colpito. Forse ora hai una situazione in cui lì è Alcuni errori di configurazione sul nuovo server e ora il codice difettoso viene premuto tramite la gestione delle eccezioni.

Puoi eseguire il debug nel codice di errore? Hai una traccia dello stack?

Altri suggerimenti

L'ho avuto di recente dopo il refactoring in un nuovo responsabile delle connessioni. Una nuova routine ha accettato una transazione in modo che potesse essere eseguita come parte di un lotto, il problema era con un blocco usando:

public IEnumerable<T> Query<T>(IDbTransaction transaction, string command, dynamic param = null)
{
  using (transaction.Connection)
  {
    using (transaction)
    {
      return transaction.Connection.Query<T>(command, new DynamicParameters(param), transaction, commandType: CommandType.StoredProcedure);
    }
  }
}

Sembra che l'uso esterno stesse chiudendo la connessione sottostante, quindi qualsiasi tentativo di commettere o rollback la transazione ha vietato il messaggio "This SqlTransaction has completed; it is no longer usable."

Ho rimosso le usi aggiunte un test di copertura e il problema è andato via.

public IEnumerable<T> Query<T>(IDbTransaction transaction, string command, dynamic param = null)
{
  return transaction.Connection.Query<T>(command, new DynamicParameters(param), transaction, commandType: CommandType.StoredProcedure);
}

Verifica qualsiasi cosa possa chiudere la connessione durante il contesto di una transazione.

Ho lo stesso problema. Questo errore si verifica perché il pooling della conozione. Quando esistono due o più utenti, il sistema, il pooling di connessione riutilizza una connessione e anche la transazione. Se il primo utente esegui il commit ou rollback, la transazione non è utilizzabile.

Di recente mi sono imbattuto in una situazione simile. Per eseguire il debug in qualsiasi versione VS IDE, apri le eccezioni da Debug (CTRL + D, E) - Controlla tutte le caselle di controllo rispetto alla colonna "lanciata" ed esegui l'applicazione in modalità Debug. Mi sono reso conto che una delle tabelle non è stata importata correttamente nel nuovo database, quindi l'eccezione SQL interna stava uccidendo la connessione, quindi risulta in questo errore.

Gist of the Story è che se il codice di lavoro in precedenza restituisce questo errore su un nuovo database, questo potrebbe essere un problema mancante dello schema del database, realizzare da sopra di cui il debug.

Spero che aiuti, Hydtechie

Nel mio caso il problema era che una delle query inclusi nella transazione sollevando un'eccezione, e anche se l'eccezione è stata "grazia" gestito è ancora riuscito a ripristinare l'intera transazione.

Il mio pseudo-codice di stato come:

var transaction = connection.BeginTransaction();
for(all the lines in a file)
{
     try{
         InsertLineInTable(); // INSERT statement might fail and throw an exception
     }
     catch {
         // notify the user about the error on line x and continue
     }
}

// Commit and Rollback will fail if one of the queries 
// in InsertLineInTable threw an exception
if(CheckTableForErrors())
{
    transaction.Commit();
}
else
{
    transaction.Rollback();
}

Controlla anche eventuali processi di lunga durata eseguiti dalla tua app .NET contro il DB. Ad esempio, potresti chiamare una procedura o una query memorizzata che non ha abbastanza tempo per finire che può mostrare nei tuoi registri come:

  • Timeout di esecuzione scaduto. Il periodo di timeout trascorso prima del completamento dell'operazione o del server non risponde.

    • Questa sqltransaction è stata completata; Non è più utilizzabile.

Controlla le impostazioni di timeout di comando, prova a eseguire una traccia (profiler) e guarda cosa sta succedendo sul lato DB ...

Nel mio caso, ho alcuni codici dopo aver commesso la transazione nello stesso blocco di cattura. Un errore può guidare l'esecuzione al blocco di cattura che contiene il rollback delle transazioni. Mostrerà l'errore simile. Ad esempio, guarda la struttura del codice seguente:

SqlTransaction trans = null;

try{
 trans = Con.BeginTransaction();
// your codes

  trans.Commit();
//your codes having errors

}
catch(Exception ex)
{
     trans.Rollback(); //transaction roll back
    // error message
}

finally
{ 
    // connection close
}

Spero che aiuti qualcuno :)

Ecco un modo per rilevare la transazione di zombi

SqlTransaction trans = connection.BeginTransaction();

//some db calls here

if (trans.Connection != null) //Detecting zombie transaction
{
  trans.Commit();
}

Decompilando la classe SQLTransaction, vedrai quanto segue

public SqlConnection Connection
{
  get
  {
    if (this.IsZombied)
      return (SqlConnection) null;
    return this._connection;
  }
}

Noto se la connessione è chiusa, il transop diventerà zombi, quindi non può Commit. Per il mio caso, è perché ho il Commit() dentro a finally blocco, mentre la connessione era in try bloccare. Questa disposizione sta causando lo smaltimento della connessione e la spazzatura. La soluzione era mettere Commit dentro il try bloccare invece.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top