Come utilizzare le transazioni COM + in un componente di Visual c ++ .NET o in un componente di Visual c ++ 2005

Il presente articolo è stato tradotto tramite il software di traduzione automatica di Microsoft e non da una persona. Microsoft offre sia articoli tradotti da persone fisiche sia articoli tradotti automaticamente da un software, in modo da rendere disponibili tutti gli articoli presenti nella nostra Knowledge Base nella lingua madre dell’utente. Tuttavia, un articolo tradotto in modo automatico non è sempre perfetto. Potrebbe contenere errori di sintassi, di grammatica o di utilizzo dei vocaboli, più o meno allo stesso modo di come una persona straniera potrebbe commettere degli errori parlando una lingua che non è la sua. Microsoft non è responsabile di alcuna imprecisione, errore o danno cagionato da qualsiasi traduzione non corretta dei contenuti o dell’utilizzo degli stessi fatto dai propri clienti. Microsoft, inoltre, aggiorna frequentemente il software di traduzione automatica.

Clicca qui per visualizzare la versione originale in inglese dell’articolo: 815814
Questo articolo è stato archiviato. L’articolo, quindi, viene offerto “così come è” e non verrà più aggiornato.
Per la una Microsoft C# versione di questo articolo, vedere 816141.
Per la una versione di Microsoft Visual Basic .NET di questo articolo, vedere 315707.

Contenuto dell'attività

RIEPILOGO
In questo articolo viene descritto come utilizzare COM + (Servizi componenti) le transazioni in una classe di Microsoft Visual c ++ .NET o in una classe di Microsoft Visual c ++ 2005. Un insieme di operazioni di database viene considerato un'unità. Tutte le operazioni di esito positivo oppure, se un'operazione non riesce, l'intera transazione avrà esito negativo. In quest'ultimo caso, le operazioni di database effettuate non vengono registrate nel database sottostante.

back to the top

Requisiti

In questo articolo si presume la conoscenza dei seguenti argomenti:
  • Concetti transazionali e di elaborazione
  • COM + (Servizi componenti)
back to the top

Servizi di transazione COM +

È possibile implementare l'elaborazione con lo spazio dei nomi System.EnterpriseServices in Microsoft .NET Framework di transazioni. Per l'accesso COM + servizi transazionali, creare una classe. Per effettuare questa operazione, attenersi alla seguente procedura:
  1. Avviare Visual Studio .NET o Visual Studio 2005.
  2. Scegliere Nuovo dal menu file , quindi progetto .
  3. In Tipi progetto fare clic su Progetti di Visual c ++ e quindi fare clic su Libreria di classi (. NET) in modelli . Nome prjEnterprise il progetto.

    Nota In Visual Studio 2005, fare clic su Visual c ++ in Tipi progetto e quindi fare clic su Libreria di classi in modelli .
  4. In Esplora soluzioni, fare clic con il pulsante destro del mouse su riferimenti e quindi fare clic su Aggiungi riferimento .
  5. Fare clic sulla scheda NET nella finestra di dialogo Aggiungi riferimento .
  6. Fare doppio clic su System.EnterpriseServices in Nome componente .
  7. Assicurarsi che System.EnterpriseServices visualizzato nella casella Componenti selezionati e quindi fare clic su OK .
  8. Aggiungere il seguente codice prima di qualsiasi altra istruzione nel file prjEnterprise.h:
    using namespace System;using namespace System::Data;using namespace System::Data::SqlTypes;using namespace System::Data::Common;using namespace System::EnterpriseServices;using namespace System::Data::SqlClient;
  9. Aggiungere una nuova classe denominata clsES al file prjEnterprise.h.
  10. Per utilizzare servizi transazionali di COM +, verificare che la classe ( clsES ) eredita funzionalità dalla classe ServicedComponent come segue:
    public __gc class clsES:public ServicedComponent
  11. Utilizzare un attributo Transaction per specificare il livello di supporto transazionale per la classe nel modo seguente:
    [Transaction(TransactionOption::Required,Timeout=5)]public __gc class clsES:public ServicedComponent
  12. Creare un metodo nella classe clsES che riceve quattro parametri di input numero intero. Nome dbAccess la classe. I primi due parametri forniscono un numero di serie e le unità in ordine per quel prodotto. I secondo di due parametri forniscono un numero di serie e le unità in scorta per quel prodotto. Questo metodo esegue una serie di operazioni di database a fronte di questi ID di prodotto specificato devono essere considerati come una transazione:
    public:	void dbAccess(int pID1, int onOrder, int pID2, int inStock)
  13. Con il metodo dbAccess creato un oggetto di connessione SQL per Northwind database e quindi aprire la connessione. Le operazioni di database si verificano utilizzando il seguente database:
    SqlConnection * Conn = new SqlConnection("user id=<username>;password=<password>;Initial Catalog=northwind;Data Source=<Your SQL Server name>;");Conn->Open();
    memorizza di Nota per modificare i parametri stringa di connessione per riflettere i valori corretti per il server di SQL Server.
  14. Consente di impostare un blocco try per acquisire tutte le eccezioni che potrebbero verificarsi durante l'elaborazione del database. È necessario intercettare le eccezioni per interrompere la transazione. Il blocco try include due operazioni di database. Ogni operazione aggiorna un campo diverso in un record della tabella prodotti specificati.
    try { 
  15. Eseguire il primo aggiornamento per la tabella prodotti. Consente di aggiornare il campo UnitsOnOrder con il valore onOrder per prodotto con ID, come specificato nei primi due parametri di input. Utilizzare il seguente comando SQL per eseguire l'aggiornamento SQL:
    SqlCommand * sqlCommand = new SqlCommand("UPDATE Products SET UnitsonOrder = @onOrderString WHERE productID = @pID1String ", Conn);sqlCommand->Parameters->Add(new SqlParameter("@onOrderString",SqlDbType::VarChar ,	40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,onOrder.ToString()));sqlCommand->Parameters->Add(new SqlParameter("@pID1String", SqlDbType::VarChar,	40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,pID1.ToString()));sqlCommand->ExecuteNonQuery();
  16. Eseguire un altro aggiornamento per la tabella products. Aggiornare il campo scorte con l'inStock valore per il prodotto con ID, come specificato nel terzo e il quarto parametro input. Utilizzare il seguente comando SQL per eseguire l'aggiornamento SQL: sqlCommand
    sqlCommand->Parameters->Add(new SqlParameter("@inStockString",SqlDbType::VarChar ,	40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,inStock.ToString()));sqlCommand->Parameters->Add(new SqlParameter("@pID2String", SqlDbType::VarChar,	40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,pID2.ToString()));sqlCommand->ExecuteNonQuery();
  17. Poiché questi aggiornamenti fanno parte di una transazione, sono salvate come una singola unità. Il metodo setComplete della classe contextUtil da dello spazio dei nomi System.EnterpriseServices viene utilizzato per il commit della transazione (in questo caso i due Aggiorna) se non sono stati generati errori:
    ContextUtil::SetComplete(); 
  18. Utilizzare il codice riportato di seguito per chiudere la connessione al database Northwind:
    Conn->Close(); }
  19. È necessario intercettare eventuali eccezioni generate durante l'esecuzione di comandi SQL in modo da poter annullare l'intera transazione:
    catch(Exception * e){ 
  20. Il metodo setAbort della classe contextUtil da dello spazio dei nomi System.EnterpriseServices viene utilizzato per interrompere l'intera transazione. Se il primo aggiornamento ha esito positivo e il secondo aggiornamento non riesce, non aggiornamento viene registrato nella tabella prodotti. Viene generata l'eccezione intercettata al chiamante, che indica che la transazione non riuscita:
    ContextUtil::SetAbort();throw e; }
  21. Per questo componente per il corretto funzionamento, è necessario che il componente necessario un nome sicuro. Consente di generare un nome sicuro e quindi di firmare l'assembly con un nome sicuro. Per effettuare questa operazione, attenersi alla seguente procedura:
    1. Al prompt di comando di Visual Studio. NET, digitare snEnterprise.snk -k sn.exe per creare un file chiave. Per ulteriori informazioni sulla firma degli assembly con nomi sicuri, vedere la documentazione di .NET Framework SDK.
    2. Copiare snEnterprise.snk la cartella di progetto.
    3. In AssemblyInfo.vc, aggiungere la riga di codice riportata di seguito prima o dopo le istruzioni di altri attributi dell'assembly:
      [assembly:AssemblyKeyFileAttribute("..\\snEnterprise.snk")]; 
    4. Salvare e quindi generare il progetto.
back to the top

Elenco completo del codice

Nota Remember to change your connection string parameters to reflect the correct values for your SQL Server server.
#pragma onceusing namespace System;using namespace System::Data;using namespace System::Data::SqlTypes;using namespace System::Data::Common;using namespace System::EnterpriseServices;using namespace System::Data::SqlClient;namespace prjEnterprise{		[Transaction(TransactionOption::Required,Timeout=5)]	public __gc class clsES:public ServicedComponent	{	public:	SqlConnection * Conn;	public:	void dbAccess(int pID1, int onOrder, int pID2, int inStock)		{			try			{							SqlConnection * Conn = new SqlConnection("user id=<username>;password=<password>;Initial Catalog=northwind;Data Source=<Your SQL Server name>;");				Conn->Open();								SqlCommand * sqlCommand = new SqlCommand("UPDATE Products SET UnitsonOrder = @onOrderString WHERE productID = @pID1String ", Conn);				sqlCommand->Parameters->Add(new SqlParameter("@onOrderString",SqlDbType::VarChar ,					40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,onOrder.ToString()));				sqlCommand->Parameters->Add(new SqlParameter("@pID1String", SqlDbType::VarChar,					40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,pID1.ToString()));				sqlCommand->ExecuteNonQuery();								sqlCommand->CommandText = "UPDATE Products SET UnitsinStock = @inStockString WHERE productID = @pID2String" ;				sqlCommand->Parameters->Add(new SqlParameter("@inStockString",SqlDbType::VarChar ,					40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,inStock.ToString()));				sqlCommand->Parameters->Add(new SqlParameter("@pID2String", SqlDbType::VarChar,					40,ParameterDirection::Input,true,0,0,"Description",DataRowVersion::Current,pID2.ToString()));				sqlCommand->ExecuteNonQuery();				ContextUtil::SetComplete();				Conn->Close();			}			catch(Exception * e)			{				ContextUtil::SetAbort();							throw e;			}					}	};}
Nota È necessario aggiungere il common language runtime supporta (opzione del compilatore) (/ CLR: oldSyntax) in Visual c ++ 2005 per compilare correttamente l'esempio di codice precedente. Per aggiungere il compilatore opzione supporto common language runtime in Visual c ++ 2005, attenersi alla seguente procedura:
  1. Fare clic su progetto e quindi scegliere <ProjectName> proprietà .

    Nota <ProjectName> è un segnaposto per il nome del progetto.
  2. Espandere la Proprietà di configurazione e quindi fare clic su Generale .
  3. Fare clic per selezionare supporto Common Language Runtime, vecchia sintassi (/ CLR: oldSyntax) nell'impostazione progetto supporto Common Language Runtime nel riquadro di destra, fare clic su Applica e scegliere OK .
Per ulteriori informazioni su common language runtime supporta (opzione del compilatore), visitare il seguente sito Web Microsoft:
/ clr (Common Language Runtime Compilation)
http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx
back to the top

Verifica del funzionamento

Per testare questo codice, è necessario creare un progetto applicazione console che utilizza la classe clsES . In un caso, una transazione ha esito positivo, e vengono aggiornati i campi QuantitàOrdinata e scorte per il prodotto specificato. Nel secondo caso, l'aggiornamento per il campo UnitsOnOrder un prodotto specificato ha esito positivo, ma l'aggiornamento per il campo scorte per un prodotto non riesce perché il numero del prodotto specificato non esiste nella tabella prodotti. In questo modo un errore di transazione, e la transazione viene ignorata.
  1. Avviare Visual Studio .NET o Visual Studio 2005.
  2. Scegliere Nuovo dal menu file , quindi progetto .
  3. In Tipi progetto fare clic su Progetti di Visual c ++ e quindi fare clic su Applicazione Console (. NET) in modelli .

    Nota In Visual Studio 2005, fare clic su Visual c ++ in Tipi progetto e quindi fare clic su Applicazione Console CLR in modelli .
  4. Nella casella di testo nome digitare testES . Assicurarsi che è selezionata l'opzione Aggiungi a soluzione .
  5. Fare clic su OK per aggiungere il progetto alla soluzione.
  6. Per testES eseguire il test prjEnterprise , è necessario aggiungere un riferimento. In Esplora soluzioni, fare clic con il pulsante destro del riferimenti sotto testES (che è stato appena aggiunto) e quindi fare clic su Aggiungi riferimento .
  7. Verrà visualizzata la finestra di dialogo Aggiungi riferimento . Nella scheda progetti , fare doppio clic su prjEnterprise .
  8. Un riferimento verrà visualizzato in selezionati componenti . Fare clic su OK per aggiungere questo riferimento al progetto.
  9. Aggiungere un riferimento al progetto lo spazio dei nomi System.EnterpriseServices . In Esplora soluzioni, fare clic con il pulsante destro del mouse su riferimenti e quindi fare clic su Aggiungi riferimento .
  10. Verrà visualizzata la finestra di dialogo Aggiungi riferimento . In Nome componente nella scheda .NET fare doppio clic su System.EnterpriseServices .
  11. Assicurarsi che sia System.EnterpriseServices visualizzato nella casella Componenti selezionati . Fare clic su OK .
  12. Fare clic con il pulsante destro del mouse su testES e quindi fare clic su Imposta come progetto di avvio .
  13. Incollare il seguente codice di origine nella funzione _tmain() della classe testES :
    prjEnterprise::clsES * myTest = new prjEnterprise::clsES();	try {	myTest->dbAccess(1, 777, 2, 888);	Console::WriteLine("TRANSACTION ONE -- SUCCESS");		myTest->dbAccess(1, 5, 2, -20);	Console::WriteLine("TRANSACTION TWO -- SUCCESS");}catch (Exception * e){	Console::WriteLine("TRANSACTION FAILURE");	//Console::WriteLine("Error Message: {0}",e->Message);	 	//uncomment this line if you must get detailed error information}
  14. Premere F5 per eseguire il codice di test.

    Nel codice nel passaggio 7, la prima chiamata a dbAccess ha esito positivo. Prodotto 1 e 2 di prodotti sono nella tabella prodotti. Il campo di onOrder per prodotto 1 viene aggiornato a 777 e inStock campo per il prodotto 2 viene aggiornato 888 . Poiché questa operazione è stata completata è visualizzato il messaggio riportato di seguito nella finestra di output:
    TRANSAZIONE ESITO UNA - POSITIVO
    La seconda chiamata a dbAccess non riuscirà. Di conseguenza, nessuna istruzione update in dbAccess alla tabella prodotti viene registrato il database. Sebbene prodotto 1 Impossibile dispone di relativo campo UnitsOnOrder aggiornato per 5 , prodotto 2 non può avere il campo UnitsInStock è impostato su -20 . A causa di un vincolo definito nella definizione della tabella prodotti, scorte non è consentito per i numeri negativi. Pertanto, questa chiamata a dbAccess ha esito negativo e l'intera transazione avrà esito negativo. La tabella prodotti mantenuta come era prima della chiamata a dbAccess . L'istruzione catch gestisce la notifica dell'errore di transazione da dbAccess , e viene visualizzato il seguente messaggio di errore nella finestra di output:
    ERRORE DI TRANSAZIONE
  15. Esaminare il contenuto della tabella prodotti di Northwind utilizzando SQL Server Enterprise Manager. Quando si visualizza il prodotto 1, il campo UnitsOnOrder è uguale a 777 . Quando si visualizza il prodotto 2, il campo scorte è 888 . Di conseguenza, la seconda chiamata a dbAccess (che avrebbe comportato valori diversi per questi campi) avrà esito negativo.
back to the top

Risoluzione dei problemi

  • Assicurarsi che qualsiasi progetto che utilizza i servizi COM + sia un nome sicuro.
  • Qualsiasi classe che utilizza i servizi COM + deve ereditare dal componente servito. Il componente servito si trova dello spazio dei nomi System.EnterpriseServices .
  • Durante il debug, una transazione può timeout prima che venga eseguito il commit o interrotta. Per evitare un timeout, utilizzare una proprietà di timeout dell'attributo di transazione. In questo esempio, il metodo associato dispone di 1.200 secondi per completare qualsiasi transazione prima del timeout:
    [Transaction(TransactionOption::Required,Timeout=1200)]
  • Puoi ricevere alcune eccezioni impreviste quando si esegue il codice. Per ottenere ulteriori informazioni su queste eccezioni, rimuovere il commento le ultime due righe nel passaggio 13:
    Console::WriteLine("Error Message: {0}",e->Message);uncomment this line if you must get detailed error information
back to the top
Riferimenti
Per ulteriori informazioni, visitare i seguenti siti Web MSDN (informazioni in lingua inglese):
COM + Integration: How .NET Enterprise Services È consentono generazione di applicazioni distribuite
Componenti serviti
back to the top
Servizio componente transazioni COM +

Avviso: questo articolo è stato tradotto automaticamente

Proprietà

ID articolo: 815814 - Ultima revisione: 01/17/2015 06:50:03 - Revisione: 3.2

Microsoft Visual C++ 2005 Express Edition, Microsoft Visual C++ .NET 2003 Standard Edition

  • kbnosurvey kbarchive kbmt kbsqlclient kbcomplusqc kbcode kbhowtomaster kbhowto KB815814 KbMtit
Feedback