2009-04-27 9 views
34

Sto tentando di utilizzare TransactionScope, ma continuo a ottenere l'eccezione di seguito. L'app è in esecuzione su una macchina diversa dal database, se questo è importante. Sto utilizzando Sql Server 2005.Come utilizzare TransactionScope in C#?

"L'accesso di rete per Distributed Transaction Manager (MSDTC) è stato disabilitato. Abilitare DTC per l'accesso alla rete nella configurazione di sicurezza per MSDTC utilizzando lo strumento di amministrazione dei componenti."

using (TransactionScope tsTransScope = new TransactionScope()) 
{ 
    //Do stuff here 
    tsTransScope.Complete(); 
} 

Modifica

ho fatto alcuni chagnes sulla base del feedback. Ora sto ottenendo questo errore:

{"Error HRESULT E_FAIL has been returned from a call to a COM component."} 
{"Communication with the underlying transaction manager has failed."} 

Soluzione Penso che la risposta accettata risolto il problema iniziale mi è stato sempre. Il secondo errore sembra essere specifico per il framework di entità. Pubblicherò un'altra domanda per questo.

Qui ci sono le proprietà del cliente: Client http://www.portnine.com/data/images/Misc/client.jpg

Ecco le proprietà sul server:

Server http://www.portnine.com/data/images/Misc/server.jpg

+0

NotDan hai ancora le immagini a cui ti eri collegato? Se è così sarebbe bello ripubblicarli per fissare il fatto che sono corretti riferimenti di immagine. – ahsteele

risposta

31

È necessario abilitare l'accesso di rete DTC come descritto in questo Microsoft TechNet Article. Questa modifica potrebbe dover essere eseguita sia sul database che sui server delle applicazioni. Spesso DTC è già stato attivato su un server di database, quindi guarderei prima il server delle applicazioni.

Ecco uno screenshot di quello che usiamo, tranne per l'opzione "Consenti amministrazione remota": Security Configuration Screenshot

non ho incontrato il problema HRESULT_E_FAIL si sta ora avendo, ma questo articolo su XP SP2 and transactions ha avuto questo interessante suggerimento:

Another configuration setting that you need to be aware (although I consider it to be an uncommon scenario) is RestrictRemoteClients registry key. If the value of this key is set to 2 (RPC_RESTRICT_REMOTE_CLIENT_HIGH) then MSDTC network transactions will not be able to work properly. MSDTC supports only RPC_RESTRICT_REMOTE_CLIENT_NONE (0) and RPC_RESTRICT_REMOTE_CLIENT_DEFAULT (1) values. See http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2netwk.mspx#XSLTsection128121120120 for more info on RestrictRemoteClients.

Infine, pur non essendo specifico per il problema una cosa molto importante da notare su come utilizzare la classe TransactionScope è che la sua impostazione di default è di utilizzare un Transaction Isolation Level of Serializable. Serializable è il più restrittivo dei livelli di isolamento e francamente è sorprendente che sia stato scelto come predefinito. Se non avete bisogno di questo livello di bloccaggio Consiglio vivamente l'impostazione del livello di isolamento a un'opzione meno restrittiva (READCOMMITTED) quando si crea un'istanza di un TransactionScope:

var scopeOptions = new TransactionOptions(); 
scopeOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted; 
scopeOptions.Timeout = TimeSpan.MaxValue; 

using (var scope = new TransactionScope(TransactionScopeOption.Required, 
    scopeOptions)) 
{ 
    // your code here 
} 
+0

Mi rendo conto che dal tuo screenshot non stai usando XP, ma pensavo che l'articolo XP SP2 potesse essere applicato. – ahsteele

+0

Penso che questo abbia risolto il problema iniziale che stavo ottenendo. Il secondo errore sembra essere specifico per il framework di entità. Pubblicherò un'altra domanda per questo. – NotDan

+2

Ho finalmente risolto questo problema. Windows Firewall stava bloccando le connessioni a MS-DTC. – NotDan

0

Se si utilizza SQL Server 2000, System.Transactions.TransactionScope causerà tutte le transazioni devono essere promosse a Transazioni Distribuite, richiedendo che MS Distributed Transaction Coordinator sia in esecuzione.

È possibile risolvere questo problema avviando il servizio MSDTC, l'aggiornamento a SQL Server 2005, o implementare qualcosa di simile la mia soluzione CodeProject: http://www.codeproject.com/KB/database/typed_dataset_transaction.aspx

ho mai avuto bisogno di farlo, ma si dovrebbe anche verificare la risposta di Ocdecio per configurare anche le impostazioni di sicurezza della rete per DTC.

+0

Aggiunta una nota sopra, Sto usando Sql Server 2005 – NotDan

2

Pannello di controllo - Strumenti di amministrazione - Servizi componenti - Proprietà del computer - scheda MSDTC - scheda Security Configuration - Accesso di rete DTC (controllato)/Consenti client remoti (controllato)/Consenti in entrata (controllato)/Consenti in uscita (controllata)/Abilita transazioni TIP (controllato)

riavvio del computer.

+0

grazie mi mancava la parte del computer di riavvio. – melaos

2

A seconda del back-end in uso, TransactionScope richiede spesso l'attivazione di Distributed Transaction Manager. Alcuni dettagli sono on this MSDN blog.

Inoltre, se si utilizzano più risorse, DTC può essere richiesto. Potrebbe essere necessario abilitare DTC nella propria situazione o accertarsi di utilizzare SQL Server 2005 e attenersi a ciò che sarebbe fattibile in transazioni leggere.

1

È necessario abilitare DTC per l'accesso alla rete nella configurazione di sicurezza per MSDTC utilizzando lo strumento di amministrazione dei servizi componenti.

0

È necessario abilitare i accesso di rete DTC sia per il server di database e il server su cui viene eseguita l'applicazione.

Sarà inoltre necessario verificare che le connessioni non vengano bloccate da un firewall. Poiché una connessione verrà avviata dal server del database al computer dell'applicazione, è altrettanto importante aggiungere MSDTC all'elenco delle eccezioni del firewall sul computer dell'applicazione.

0

Ho avuto lo stesso problema durante l'esecuzione di test di integrazione.

ho postato una domanda su questo here

ma alla fine ho trovato un modo intorno ad esso. Anche se, non lo consiglierei di farlo per il codice di produzione. Lo stavo facendo nel contesto del test.