Como utilizar transacções COM + num componente Visual C++ .NET ou num componente Visual C++ 2005

Traduções de Artigos Traduções de Artigos
Artigo: 815814 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

RESUMO

Este artigo passo a passo descreve como utilizar o COM + (Serviços de componentes) transações numa classe Microsoft Visual C++ .NET ou numa classe Microsoft Visual C++ 2005. Um conjunto de operações de base de dados é considerado como uma unidade. Como todas as operações tiveram êxito ou, se uma operação falhar, a transacção inteira falha. Neste último caso, quaisquer operações de base de dados que foram tentadas não são registadas na base de dados subjacente.

Requisitos

Este artigo pressupõe que está familiarizado com os seguintes tópicos:
  • Conceitos de transacções e processamento
  • COM + (Serviços de componentes)

Serviços de transacção COM +

Pode implementar transacções processar com o espaço de nomes System.EnterpriseServices no Microsoft .NET Framework. Para acesso COM + Serviços transaccionais, crie uma classe. Para o fazer, siga estes passos:
  1. Inicie o Visual Studio .NET ou Visual Studio 2005.
  2. No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
  3. Em Project Types , clique em Projectos do Visual C++ e clique em Biblioteca de classe (NET) em modelos . Nome prjEnterprise projecto.

    Nota No Visual Studio 2005, clique em Visual C++ em Project Types e, em seguida, clique em Biblioteca de classes em modelos .
  4. No Solution Explorer, clique com o botão direito do rato em References e, em seguida, clique em Add Reference .
  5. Clique no separador NET na caixa de diálogo Adicionar referência .
  6. Faça duplo clique em System.EnterpriseServices em nome do componente .
  7. Certifique-se de que System.EnterpriseServices aparece em Componentes seleccionados e, em seguida, clique em OK .
  8. Adicione o seguinte código antes de quaisquer outras instruções no ficheiro 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. Adicionar uma classe nova com o nome clsES para o ficheiro prjEnterprise.h.
  10. Para utilizar serviços de transaccional COM +, certifique-se de que a classe ( clsES ) herda funcionalidade a classe de ServicedComponent da seguinte forma:
    public __gc class clsES:public ServicedComponent
    
  11. Utilizar um atributo de transacções para especificar o nível de suporte transaccional para a classe da seguinte forma:
    [Transaction(TransactionOption::Required,Timeout=5)]public __gc class clsES:public ServicedComponent
    
  12. Crie um método na classe clsES que recebe quatro parâmetros de entrada inteiro. Nome dbAccess classe. Os primeiros dois parâmetros fornecem um ID do produto e as unidades na encomenda para esse produto. Os parâmetros de dois segundos fornecem um ID do produto e as unidades em stock para esse produto. Este método efectua um conjunto de operações de base de dados nestes IDs de produto especificado estão a ser tratada como uma transacção:
    public:	void dbAccess(int pID1, int onOrder, int pID2, int inStock)
  13. Método dbAccess , criar um objecto de ligação SQL para a base da base de dados e abra a ligação. Operações de base de dados ocorrem utilizando a base de dados seguinte:
    SqlConnection * Conn = new SqlConnection("user id=<username>;password=<password>;Initial Catalog=northwind;Data Source=<Your SQL Server name>;");
    Conn->Open();
    memorizar a Nota para alterar os parâmetros de cadeia de ligação para reflectir os valores correctos para o servidor de SQL Server.
  14. Defina um bloco tente capturar quaisquer excepções que poderão ocorrer durante o processamento da base de dados. Tem a detectar estas excepções para abortar a transacção. O bloco tente inclui duas operações de base de dados. Cada operação actualiza um campo diferente num registo de tabela de produtos especificado.
    try { 
    
  15. Execute a primeira actualização à tabela produtos. Actualizar o campo UnidadesEncomendadas com o valor de onOrder para produtos com o ID, tal como especificado nos primeiros dois parâmetros de entrada. Utilize o seguinte comando SQL para executar esta actualização 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. Efectue outra actualização à tabela produtos. Actualizar o campo Existências com o inStock valor para o produto com o ID, como especificado nos parâmetros de entrada de terceiro e quarto. Utilize o seguinte comando SQL para executar esta actualização SQL:
    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. Uma vez que estas actualizações fazem parte de uma transacção COM +, são consolidadas como uma unidade. O método setComplete da classe contextUtil do espaço de nomes System.EnterpriseServices é utilizado para consolidar a transacção (neste caso as duas actualizações de) se erros não foram iniciados:
    ContextUtil::SetComplete(); 
    
  18. Utilize o seguinte código para fechar a ligação à base de dados Adamastor:
    Conn->Close(); }
    
  19. Tem de detectar quaisquer excepções ocorrem ao executar os comandos SQL, de modo que pode cancelar a transacção inteira:
    catch(Exception * e){ 
    
  20. O método setAbort da classe contextUtil do espaço de nomes System.EnterpriseServices é utilizado para abortar a transacção completa. Se a primeira actualização tiver êxito e a segunda actualização falha, é registada nenhum actualização à tabela de produtos. O caught excepção ao emissor, que indica que a transacção falhou:
    ContextUtil::SetAbort();
    throw e; }
    
  21. Para este componente para funcionar correctamente, o componente tem de ter um nome seguro. Gerar um nome seguro e, em seguida, iniciar sessão a assemblagem com nome seguro. Para o fazer, siga estes passos:
    1. Na linha de comandos Visual Studio. NET, escreva sn.exe -k snEnterprise.snk para criar um ficheiro de chave. Para obter mais informações sobre assemblagens assinatura com nomes seguros, consulte a documentação do .NET Framework SDK.
    2. Copie snEnterprise.snk para a pasta de projecto.
    3. No AssemblyInfo.vc, adicione a seguinte linha de código antes ou depois de outras instruções de atributo de assemblagem:
      [assembly:AssemblyKeyFileAttribute("..\\snEnterprise.snk")]; 
    4. Guarde e, em seguida, criar o projecto.

Listagem de código completo

Nota Remember to change your connection string parameters to reflect the correct values for your SQL Server server.
#pragma once

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;

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 tem de adicionar o common language runtime suportam a opção do compilador (/ clr:oldSyntax) no Visual C++ 2005 a compilação com êxito o anterior exemplo de código. Para adicionar a opção de compilador do suporte de tempo de execução idioma comum no Visual C++ 2005, siga estes passos:
  1. Clique em Project e, em seguida, clique em <ProjectName> propriedades .

    Nota <ProjectName> é um marcador de posição para o nome do projecto.
  2. Expanda Propriedades de configuração e, em seguida, clique em Geral .
  3. Clique para seleccionar Runtime do idioma comum suporte, sintaxe antigo (/ clr:oldSyntax) na definição de projecto Common Language Runtime suporte no painel da direita, clique em Aplicar e, em seguida, clique em OK .
Para obter mais informações sobre o common language runtime suporte a opção do compilador, visite o seguinte Web site da Microsoft:
/ clr (Common Language Runtime compilação)
http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

Verificar se funciona

Para testar este código, crie um projecto de aplicação de consola que utiliza a classe clsES . Num caso, uma transacção tiver êxito e os campos UnidadesEncomendadas e Existências para o produto especificado são actualizados. No segundo caso, a actualização para o campo UnidadesEncomendadas para um produto especificado tiver êxito, mas a actualização para o campo Existências para um produto falhar porque o número de produto especificada não existe na tabela produtos. Isto provoca uma falha de transacção e a transacção é ignorada.
  1. Iniciar Visual Studio .NET ou Visual Studio 2005.
  2. No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
  3. Em Project Types , clique em Projectos do Visual C++ e clique em Consola de aplicações (NET) em modelos .

    Nota No Visual Studio 2005, clique em Visual C++ em Project Types e, em seguida, clique em CLR da consola de aplicações em modelos .
  4. Na caixa de texto nome , escreva testES . Certifique-se que a opção Adicionar solução está seleccionada.
  5. Clique em OK para adicionar este projecto para a solução.
  6. Para testES testar prjEnterprise , tem de adicionar uma referência. No Solution Explorer, clique com o botão direito do rato em referências em testES (que acabou de adicionar) e, em seguida, clique em Add Reference .
  7. A caixa de diálogo Adicionar referência do é apresentada. No separador projectos , faça duplo clique em prjEnterprise .
  8. Uma referência aparece em seleccionado componentes . Clique em OK para adicionar esta referência ao projecto.
  9. Adicione uma referência ao projecto ao espaço de nomes System.EnterpriseServices . No Solution Explorer, clique com o botão direito do rato em References e, em seguida, clique em Add Reference .
  10. A caixa de diálogo Adicionar referência do é apresentada. Em Nome do componente no separador .NET , clique duas vezes System.EnterpriseServices .
  11. Certifique-se de que System.EnterpriseServices é apresentado em Componentes seleccionados . Clique em OK .
  12. Clique com o botão direito do rato testES e clique em Definir como projecto de arranque .
  13. Cole o seguinte código origem na função _tmain() da 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. Prima F5 para executar o código de teste.

    No código no passo 7, a primeira chamada para dbAccess terá êxito. Produto 1 e 2 do produto são na tabela produtos. O campo onOrder para o produto 1 é actualizado para 777 e o inStock campo para o produto 2 é actualizado para 888 . Uma vez que esta transacção teve êxito, receberá a mensagem seguinte na janela de resultados:
    TRANSACÇÃO ÊXITO DE UM-
    A segunda chamada dbAccess falha. Deste modo, nenhuma instrução de actualização dbAccess à tabela produtos é registada na base de dados. Apesar do produto 1 pode ter o respectivo campo UnidadesEncomendadas actualizado para 5 , produto 2 não é possível ter o campo Existências definido como -20 . Devido a uma restrição definido na definição da tabela Produto, Existências não é permitido para que os números negativos. Por conseguinte, esta chamada para dbAccess falha e a transacção inteira falha. A tabela Produtos permanece tal como estava antes da chamada para dbAccess . A instrução ' catch processa a notificação de falha de transacção de dbAccess e receberá a seguinte mensagem de erro na janela de resultados:
    FALHA DE TRANSACÇÃO
  15. Examine o conteúdo da tabela produtos de base de dados Adamastor utilizando o SQL Server Enterprise Manager. Quando visualiza o produto 1, o campo UnidadesEncomendadas é igual a 777 . Quando visualiza o produto 2, o campo Existências é 888 . Por conseguinte, a segunda chamada dbAccess (o que resultaria em valores diferentes para estes campos) falha.

Resolução de problemas

  • Certifique-se que qualquer projecto que utiliza serviços COM + tem um nome seguro.
  • Qualquer classe que utiliza serviços COM + tem Herdar do componente de serviço. O componente serviço está localizado no espaço de nomes de System.EnterpriseServices .
  • Durante a depuração, uma transacção pode limite de tempo antes de serem consolidada ou abortada. Para evitar um tempo limite, utilize uma propriedade de tempo de espera no atributo transacção. No exemplo seguinte, o método associado tem 1.200 segundos para concluir quaisquer transacções antes de o tempo limite:
    [Transaction(TransactionOption::Required,Timeout=1200)]
    
  • Poderá receber algumas excepções inesperadas quando executar o código. Para receber mais informações sobre estas excepções, uncomment as últimas duas linhas no passo 13:
    Console::WriteLine("Error Message: {0}",e->Message);
    uncomment this line if you must get detailed error information

Referências

Para obter informações adicionais, visite os seguintes Web sites da Microsoft Developer Network (MSDN):
Integração COM +: Como .NET Enterprise Services podem ajudar é criar aplicações distribuídas
Componentes do serviço

Propriedades

Artigo: 815814 - Última revisão: 14 de novembro de 2007 - Revisão: 3.2
A informação contida neste artigo aplica-se a:
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition
Palavras-chave: 
kbmt kbsqlclient kbcomplusqc kbcode kbhowtomaster kbhowto KB815814 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 815814

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com