Compartilhar via


Este artigo foi traduzido por máquina.

The Polyglot Programmer

Transações ACID com o STM.NET

Ted Neward

Embora esta coluna concentra-se especificamente em linguagens de programação, é interessante observar como idioma idéias podem às vezes, sangria sobre em outros idiomas sem modificá-los diretamente.

Um exemplo é o idioma do Microsoft Research C-ômega (às vezes gravado cw, desde que o símbolo de ômega grego é muito parecido com um w em minúscula no layout de teclado dos EUA). Juntamente com a introdução de um número de conceitos unificar dados e código que eventualmente faz seu caminho em idiomas translation from VPE for Csharp e Visual Basic como LINQ, ômega C também é oferecido até um novo meio de simultaneidade chamado chords posteriormente chegou em uma biblioteca conhecidas como associações. Enquanto não tiver, associações de redação deste artigo, feita programa está em um produto (mas), o fato de que o chords todo conceito de simultaneidade pode ser fornecido por meio de uma biblioteca significa que qualquer translation from VPE for Csharp comum ou Visual Basic (ou outra linguagem .NET) poderia fazer usá-lo.

Outro esse esforço é o recurso de código contratos, disponível a partir do site do Microsoft DevLabs e discutido a edição de agosto de 2009 da MSDN Magazine . Design por contrato é um recurso de idioma que foi evidentes em linguagens como Eiffel e veio originalmente para o .NET através da linguagem Microsoft Research especificação #. Tipos semelhantes de sistemas de garantia contratuais passaram por meio de pesquisa da Microsoft, incluindo um dos Meus Favoritos, Fugue, qual exerceu de atributos personalizados e análise estática para fornecer verificação de correção de código do cliente.

Uma vez, embora contratos de código ainda não foi fornecido como um produto formal ou com uma licença que permita seu uso em produção software, o fato de que ele existe como uma biblioteca em vez de uma linguagem autônoma implica duas coisas. Primeiro, o que ele poderia (na teoria) ser escrito como uma biblioteca por qualquer desenvolvedor .NET suficientemente determinados a ter tipos semelhantes de funcionalidade. E em segundo lugar, que (supondo que ele é fornecido) disse funcionalidade pode estar disponível em uma grande variedade de linguagens, inclusive translation from VPE for Csharp e Visual Basic.

Se estiver detecção um tema, você está certo. Este mês desejo concentrar ainda outra biblioteca provenientes do mundo idioma polyglot anunciou recentemente: software memória transacional ou STM. A biblioteca STM.NET está disponível para download via o site DevLabs, mas em contraste perfeito para algumas das outras implementações já mencionei, não é uma biblioteca autônoma que obtém vinculada em seu programa ou que é executado como uma ferramenta de análise estática — é um substituto e o suplemento para a biblioteca de classes base do .NET como um todo, dentre outras coisas.

Observe, entretanto, se a implementação atual do STM.NET não é muito compatível com betas atuais do Visual Studio 2010, para que o usuais isenções de responsabilidade sobre como instalar software inacabada/beta/CTP em máquinas que você se preocupa se aplicam duplamente assim, neste caso. Ele deve instalar o lado a lado com o Visual Studio 2008, mas eu ainda não colocá-la na sua máquina de trabalho. Este é outro caso em que o Virtual PC é muito bom amigo.

Inícios

O plano de fundo lingüístico da STM.NET vem de um número de locais diferentes, mas a idéia conceitual STM é surpreendentemente simples e familiar: em vez de forçar os desenvolvedores a concentrar os meios de tornar as coisas simultâneas (enfocando bloqueios e outros), permitem Mark quais partes do código devem executar sob certas características de simultaneidade amigável e deixar que a ferramenta de idioma (interpretador ou compilador) gerencie os bloqueios conforme necessário. Em outras palavras, como usuários e administradores de banco de dados, permitem que o programador Mark o código com o estilo de ACID semântica transacional e deixe o trabalho pesado de gerenciar bloqueios para o ambiente subjacente.

Enquanto os bits STM.NET podem parecer estar apenas outra tentativa de gerenciamento de simultaneidade, o esforço STM representa algo mais profundo que que — ele tenta trazer todos os quatro qualidades de banco de dados de transação ACID ao modelo de programação na memória. Além de gerenciar os bloqueios em nome do programador, modelo STM também fornece atomicidade, consistência, isolamento e durabilidade, que deles pode fazer programação muito mais simples, independentemente da presença de vários threads de execução.

Por exemplo, considere este exemplo pseudocódigo (reconhecidamente totalmente superutilizados):

BankTransfer(Account from, Account to, int amount) {
  from.Debit(amount);
  to.Credit(amount);
}

O que acontece se o crédito falha e lança uma exceção? Claramente o usuário não será feliz se o débito para a conta ainda permanece no registro quando o crédito da conta não estiver lá, que significa agora que o desenvolvedor tem algum trabalho adicional para fazer:

BankTransfer(Account from, Account to, int amount) {
  int originalFromAmount = from.Amount;
  int originalToAmount = to.Amount;
  try {
    from.Debit(amount);
    to.Credit(amount);
  }
  catch (Exception x) {
    from.Amount = originalFromAmount;
    to.Amount = originalToAmount;
  }
}

Isso parece, pelo primeiro blush, ser um exagero. No entanto, lembre-se de que dependendo da implementação exata dos métodos de débito e crédito, exceções podem ser lançadas antes da conclusão da operação de débito ou após a operação de crédito for concluída (mas não termine). Isso significa que o método BankTransfer deve garantir que todos os dados referenciados e usado nesta operação retorna ao exatamente o estado em que estava quando o início da operação.

Se este BankTransfer cheguem no tudo mais complicada — operando em três ou quatro itens ao mesmo tempo, por exemplo — o código de recuperação no bloco catch vai ficar realmente feio, realmente rapidamente. E este padrão mostra muito mais freqüência que gostaria de admitir.

Outro ponto digno de nota é isolamento. No código original, outro thread poderia ler um saldo incorreto enquanto estava sendo executado e corromper pelo menos uma das contas. Além disso, se você simplesmente slapped um bloqueio em torno dele, você poderia deadlock se o de/para pares não foram pedidos sempre. STM apenas cuida do que para você sem usar bloqueios.

Se, em vez disso, o idioma oferecidos algum tipo de operação transacional, como uma palavra-chave atômica tratado o bloqueio e lógica de falha/reversão sob o capô, assim como BEGIN TRANSACTION/COMMIT tem para um banco de dados, codificação exemplo BankTransfer se torna simples como este:

BankTransfer(Account from, Account to, int amount) {
  atomic {
    from.Debit(amount);
    to.Credit(amount);
  }
}

Você tem que admitir, isso é muito menos preocupar.

A abordagem STM.NET, no entanto, sendo biblioteca com base, não vai obter bem essa muito, pois o idioma translation from VPE for Csharp não permite que bastante que grau de flexibilidade sintática. Em vez disso, você vai trabalhar com algo ao longo das linhas de:

public static void Transfer(
  BankAccount from, BankAccount to, int amount) {
  Atomic.Do(() => {
    // Be optimistic, credit the beneficiary first
    to.ModifyBalance(amount);
    from.ModifyBalance(-amount);
  });
}

Percepções: É realmente uma alteração de idioma

No curso de revisão coluna da Neward, uma coisa entrou check-out por mim como, infelizmente, uma má interpretação básica. Neward tenta dividir extensões de linguagem em aqueles que exigem alterações de idioma e os que estão (puramente) biblioteca de alterações. Ele tenta classificar STM.NET como o último — uma alteração somente biblioteca — enquanto eu argumentaria mais bastante não é.

Uma extensão somente de biblioteca é uma implementação totalmente no idioma existente. Existem sistemas STM biblioteca; esses geralmente exigem que os dados que devem ter a semântica transacional ser declaradas de algum tipo especial, tal como “ TransactionalInt ”. STM.NET não é como o — fornece semântica transacional para dados comuns de forma transparente, simplesmente em virtude de que estão sendo acessados dentro do escopo (dinâmico) de uma transação.

Isso requer que cada leitura e gravação ocorrendo no código executado dentro da transação seja modificado para tornar adicionais associados a chamadas que adquirir bloqueios necessários, criar e preencher as cópias de sombra e assim por diante. Nossa implementação, modificamos compilador JIT do CLR extensivamente para produzir código muito diferente a ser executado dentro de transações. A palavra-chave atômica (mesmo se nós apresentada por meio de uma API baseada em delegate) altera a semântica do idioma em um nível bastante fundamental.

Assim, eu afirmam que nós alterar o idioma. Em uma linguagem .NET como translation from VPE for Csharp, a semântica de linguagem é implementada por uma combinação do compilador da linguagem do nível do código-fonte e suas suposições sobre a semântica do MSIL que emite — como o tempo de execução do CLR executará essa IL. Alteramos radicalmente a interpretação do CLR bytecodes, portanto, eu diria que isso altera o idioma.

Em particular, digamos que o compilador JIT do CLR encontra código como este:

try {<br xmlns="http://www.w3.org/1999/xhtml" /> <body> <br xmlns="http://www.w3.org/1999/xhtml" />} <br xmlns="http://www.w3.org/1999/xhtml" />catch (AtomicMarkerException) {}

O código no < body > (e repetidamente, dentro de métodos que ele chama) dinamicamente são modificados para garantir a semântica transacional. Eu deve enfatizar que tem absolutamente nada a ver com a manipulação de exceção — é puramente uma invasão para identificar um bloco atômico, já que a instrução try/catch é o único mecanismo disponível na IL para identificar um bloco com escopo léxico. A longo prazo, seria queremos algo mais como um bloco de “ atômico ” explícito no idioma IL. A interface delegado é implementada em termos de neste bloco ersatz atômico.

Em resumo, o bloco atômico nível IL, expresso no entanto, realmente é alterada a semântica do código executado de forma fundamental. Esse é o motivo pelo qual STM.NET contém um runtime CLR significativamente modificado, novo, não apenas as alterações da BCL. Se você levou um tempo de execução das ações do CLR e foi executado com a BCL do STM.NET, o resultado não daria você semântica transacional (na verdade, duvido funcionaria em todos os).

— Dr. Dave Detlefs, arquiteto, Common Language Runtime, Microsoft

A sintaxe não é tão elegante como seria uma palavra-chave atômica, mas translation from VPE for Csharp tem o poder dos métodos anônimos para capturar o bloco de código que seria constituem o corpo do bloco atômico desejado e, portanto, podem ser executada em tipos semelhantes de semântica. (Desculpe, mas como da redação deste artigo, o esforço de incubação STM.NET suporta apenas translation from VPE for Csharp. Há há motivo técnico por que ele não pôde ser estendido a todos os idiomas, mas a equipe STM.NET apenas voltada translation from VPE for Csharp para a primeira versão).

Introdução ao STM.NET

A primeira coisa que você precisará fazer é baixar a versão beta do Microsoft .NET Framework 4 1 ativado para usar software transacional memória V1.0 bits (um longos nome, o que eu irá diminuir a BCL STM.NET ou apenas STM.NET) do site DevLabs. Enquanto você estiver lá, faça download STM.NET documentação e exemplos também. É o primeiro as ferramentas BCL e STM.NET reais e conjuntos de módulos complementares, e o segundo contém, entre a documentação e projetos de exemplo, um modelo do Visual Studio 2008 para a criação de aplicativos STM.Net.

Criando um novo aplicativo habilitado para STM.NET começa como qualquer outro aplicativo, na caixa de diálogo New Project (consulte 1 Figura ). Selecione o modelo TMConsoleApplication faz duas coisas, alguns deles não são totalmente intuitivos. Por exemplo, como da redação deste artigo, para executar contra as bibliotecas STM.NET app.config do aplicativo .NET requer esse pouco de controle de versão legerdemain:

Figura 1 Iniciando um novo projeto com o modelo TMConsoleApplication

image: Starting a New Project with the TMConsoleApplication Template

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
  <startup> 
    <requiredRuntime version="v4.0.20506"/> 
  </startup>
  ... 
</configuration>

Outras configurações estarão presentes, mas o valor requiredRuntime é necessário saber a correção de iniciador CLR vincular com a versão STM.NET do tempo de execução. Além disso, o modelo TMConsoleApplication vincula o conjunto em relação a versões de mscorlib e System.Transactions assemblies instalados no diretório onde STM.NET está instalado, em vez das versões que vêm com o .NET Framework 3.0 ou 3.5 CLR de estoque. Isso é necessário, quando você pensar nisso, porque se STM.NET para fornecer acesso transacional para qualquer coisa além apenas do código que você escreve, será necessário usar sua própria cópia de mscorlib. Além disso, se for corretamente interagir com outros formulários de transações — como as transações leves fornecidas pelo LTM (Lightweight Transaction Manager) — ele precisa ter sua própria versão de System.Transactions também.

Fora isso, um aplicativo STM.NET será um aplicativo .NET tradicional, escritos em translation from VPE for Csharp e compilados para IL, vinculado com o resto do .NET assemblies sem modificações e assim por diante. STM.NET assemblies, como os componentes COM + e EnterpriseServices da última década, terá mais algumas extensões delas descrevendo transacional comportamentos para os métodos que interagem com o comportamento transacional STM.NET mas abordarei que in-time.

Olá, STM.NET

Como com o exemplo Axum na edição de setembro de 2009 MSDN Magazine, escrevendo um aplicativo Hello World tradicional como o ponto de partida para STM.NET é na verdade, mais difícil do que você pode pensar primeiro, grande parte porque se você escrevê-lo sem a preocupação de transações, é exatamente o mesmo que a tradicional translation from VPE for Csharp Hello World. Se você escrever para aproveitar o comportamento transacional STM.NET, você deve considerar o fato de que escrever o texto para o console é, na verdade, um método un-undoable (pelo menos tão longe respeito STM.NET), que significa que tentar reverter uma instrução console.WriteLine é difícil.

Portanto, em vez disso, let’s veja um exemplo simples do guia do usuário STM.NET como uma demonstração rápida dos bits STM.NET. Um objeto (denominado MyObject) tem duas cadeias de caracteres particulares e um método para definir essas duas cadeias de caracteres para algum par de valores:

class MyObject {
  private string m_string1 = "1";
  private string m_string2 = "2";

  public bool Validate() {
    return (m_string1.Equals(m_string2) == false);
  }
  public void SetStrings(string s1, string s2) {
    m_string1 = s1;
    Thread.Sleep(1);   // simulates some work 
    m_string2 = s2;
  }
}

Como a atribuição do parâmetro para o campo é uma operação atômica, não há nenhuma preocupação em torno de simultaneidade lá. Mas assim como com o exemplo BankAccount mostrado anteriormente, você deseja que seja tanto a ser definida ou nenhum dos e Don deseja ver atualizações parciais — uma seqüência de caracteres que está sendo definida, mas Don no outro — durante a operação do conjunto. Você irá gerar dois threads cegamente definir repetidamente as seqüências de caracteres e um terceiro segmento para validar o conteúdo da instância MyObject, uma violação de emissão de relatórios no caso de validar retorna false (consulte do Figura 2).

Figura 2 manualmente Validando atômica atualizações para MyObject

[AtomicNotSupported]
static void Main(string[] args) {
  MyObject obj = new MyObject();
  int completionCounter = 0; int iterations = 1000;
  bool violations = false;

  Thread t1 = new Thread(new ThreadStart(delegate {
    for (int i = 0; i < iterations; i++)
      obj.SetStrings("Hello", "World");
    completionCounter++;
  }));

  Thread t2 = new Thread(new ThreadStart(delegate {
    for (int i = 0; i < iterations; i++)
      obj.SetStrings("World", "Hello");
    completionCounter++;
  }));

  Thread t3 = new Thread(new ThreadStart(delegate {
    while (completionCounter < 2) {
      if (!obj.Validate()) {
        Console.WriteLine("Violation!");
        violations = true;
      }
    }
  }));

  t1.Start(); t2.Start(); t3.Start();
  while (completionCounter < 2)
    Thread.Sleep(1000);

  Console.WriteLine("Violations: " + violations);
...

Observe que a forma como este exemplo é construído, validação falhar se as duas seqüências de caracteres obj estiverem definidas para a mesma coisa, indicando que t1 de Thread SetStrings(“Hello”, “World”) é parcialmente atualizada (deixando o primeiro “ Hello ” para coincidir com o segundo “ Hello ” definido pelo N2).

Superficial rapidamente durante a implementação SetStrings mostra que esse código é raramente thread-safe. Se ocorrer uma alternância de segmento intermediário (que provavelmente recebe a chamada thread.Sleep, que fará com que o thread em execução desistir sua fração de tempo), outro thread poderia facilmente saltar no meio de SetStrings novamente, colocar a instância de MyObject em um estado inválido. Executá-lo e com suficiente iterações violações iniciará apareça. (No meu laptop, tive de executá-lo duas vezes antes de obteve as violações, provando que só porque ele é executado sem erro uma vez não significa que o código não tem um bug de simultaneidade.)

Modificar esta opção para usar STM.NET requer apenas uma pequena alteração para a classe MyObject, conforme mostrado no do Figura 3.

Figura 3 Validando MyObject com STM.NET

class MyObject {
  private string m_string1 = "1";
  private string m_string2 = "2";

  public bool Validate() {
    bool result = false;
    Atomic.Do(() => { 
      result = (m_string1.Equals(m_string2) == false);
    });
    return result;
  }

  public void SetStrings(string s1, string s2) {
    Atomic.Do(() => {
      m_string1 = s1;
      Thread.Sleep(1); // simulates some work 
      m_string2 = s2;
    });
  }
}

Como você pode ver, a modificação apenas necessária foi para dispor os corpos de validar e SetStrings em métodos atômicos usando a operação Atomic.Do. Agora, quando executado, nenhuma violações aparecem.

Afinidade transacional

Observant leitores serão ter observado o atributo [AtomicNotSupported] na parte superior do método Main no do Figura 2 e talvez pensou em sua finalidade ou até mesmo se perguntou se ele servidos a mesma finalidade que os atributos de dias COM +. Na verdade, está totalmente correto: o ambiente STM.NET precisa alguma ajuda na compreensão se chamado durante um bloco atômica métodos são amigável de transação para que ele pode fornecer o suporte necessário e desejável para esses métodos.

Esses três atributos estão disponíveis na versão STM.NET atual:

  • AtomicSupported — o assembly, método, campo ou delegar oferece suporte ao comportamento transacional e pode ser usado dentro ou fora dos blocos atômicos com êxito.
  • AtomicNotSupported — o assembly, método ou delegate não oferece suporte a comportamento transacional e, portanto, não deve ser usado dentro de blocos atômicos.
  • AtomicRequired — o assembly, método, campo ou delegate não só oferece suporte comportamento transacional, ela deve ser usada somente dentro de blocos atômicos (assim, garantindo que usar este item será sempre ser feito em semântica transacional).

Tecnicamente é um quarto, AtomicUnchecked, que informa ao STM.NET que este item não deve ser verificado, período. Ele serve como uma escape Hachura para evitar completamente o código de verificação.

A presença do atributo AtomicNotSupported é o que leva o sistema STM.NET para lançar um AtomicContractViolationException quando o código a seguir (simples) é tentado:

[AtomicNotSupported]
static void Main(string[] args) {
  Atomic.Do( () => {
    Console.WriteLine("Howdy, world!");
  });

  System.Console.WriteLine("Simulation done");
}

Porque o método System.Console.WriteLine não está marcado com AtomicSupported, o método Atomic.Do lança a exceção quando vir a chamada no bloco de atômica. Esse bit de segurança garante que apenas transação amigável métodos são executados dentro do bloco atômico e fornece esse bit adicional de proteção e segurança para o código.

Olá, STM.NET (parte dois)

E se você realmente, realmente deseja gravar o tradicional Hello World? E se você realmente deseja imprimir uma linha para o console (ou gravar em um arquivo ou executar algum comportamento não-transacional) juntamente com duas operações transacionais, mas apenas imprimi-la se ambas essas outras operações bem-sucedido? STM.NET oferece três maneiras de lidar com essa situação.

Primeiro, você pode executar a operação não-transacional fora da transação (e somente depois que a transação confirmada) colocando o código dentro de um bloco passado para Atomic.DoAfterCommit. Como o código dentro desse bloco geralmente deseja usar dados gerados ou modificação de dentro da transação, DoAfterCommit assume um parâmetro de contexto que é passado de dentro da transação para o bloco de código como seu único parâmetro.

Em segundo lugar, você pode criar uma ação de compensação que será executada no caso da transação falha em última análise, chamando Atomic.DoWithCompensation, que (novamente) leva um parâmetro de contexto para dados de empacotamento de dentro da transação para a confirmação ou compensar o bloco de código (conforme apropriado).

Em terceiro lugar, você pode ir completamente e criar um Gerenciador de recursos transacional (RM) que entenda como participar com o sistema transacional STM.NET. Isso é realmente menos difícil do que pode parecer — Basta herdar da classe STM.NET TransactionalOperation, que tem OnCommit e OnAbort métodos que substituem para fornecer o comportamento apropriado em ambos os casos. Ao usar esse novo tipo de mecanismo de retenção, chame OnOperation no início do seu trabalho com ele (inscrição com eficácia o recurso na transação STM.NET). Em seguida, chame FailOperation no caso de falham de operações ao redor.

Portanto, se você quiser gravar transacionalmente alguns fluxo baseado em texto, você pode escrever um Gerenciador de recursos acrescentando texto como a mostrada no do Figura 4. Este então permite que você — na verdade, em virtude do atributo [atômico Required] requer que você — para gravar alguns fluxo de texto via TxAppender enquanto dentro de um bloco atômico (consulte do Figura 5).

Figura 4 de de Um Gerenciador de recursos transacionais

public class TxAppender : TransactionalOperation {
  private TextWriter m_tw;
  private List<string> m_lines;

  public TxAppender(TextWriter tw) : base() {
    m_tw = tw;
    m_lines = new List<string>();
  }

  // This is the only supported public method
  [AtomicRequired]
  public void Append(string line) {
    OnOperation();

    try {
      m_lines.Add(line);
    }
    catch (Exception e) {
      FailOperation();
      throw e;
    }
  }

  protected override void OnCommit() {
    foreach (string line in m_lines) {
      m_tw.WriteLine(line);
    }
    m_lines = new List<string>();
  }

  protected override void OnAbort() {
    m_lines.Clear();
  }
}

Figura 5 usando TxAppender

public static void Test13() {
  TxAppender tracer = 
    new TxAppender(Console.Out);
  Console.WriteLine(
    "Before transactions. m_balance= " + 
    m_balance);

  Atomic.Do(delegate() {
    tracer.Append("Append 1:  " + m_balance);
    m_balance = m_balance + 1;
    tracer.Append("Append 2:  " + m_balance);
  });
            
  Console.WriteLine(
    "After transactions. m_balance= " 
    + m_balance);

  Atomic.Do(delegate() {
    tracer.Append("Append 1:  " + m_balance);
    m_balance = m_balance + 1;
    tracer.Append("Append 2:  " + m_balance);
  });

  Console.WriteLine(
    "After transactions. m_balance= " 
    + m_balance);
}

Isso é, obviamente, a rota mais tempo e será adequado somente em determinados cenários. Ele poderá falhar para alguns tipos de tipos de mídia, mas na maior parte, se todo o comportamento irreversível real é adiado para o método OnCommit, isso será suficiente para a maioria das necessidades transacionais em processo.

Colocar STM.NET para funcionar

Trabalhando com um STM sistema demora um pouco acostumar ao, mas depois que você está acclimated, trabalhando sem ele pode se sentir enfraquecer. Considere alguns dos possíveis locais onde usar STM.NET pode simplificar a codificação.

É ao trabalhar com outros recursos transacionados, STM.NET conectado aos sistemas existentes transacionados rápida e facilmente, tornando a única origem do código transacionado Atomic.Do no seu sistema. Exemplos STM.NET demonstram isso em uma amostra TraditionalTransactions, postando mensagens para uma fila particular MSMQ e tornando óbvio que, quando o bloco atômica falha, nenhuma mensagem é lançada para a fila. Esse é provavelmente o uso mais óbvio.

Nas caixas de diálogo — principalmente para os processos de várias etapas do assistente ou caixas de diálogo de configurações — a capacidade de reverter alterações para a caixa de diálogo de configurações ou membros de dados quando o usuário pressiona o botão Cancel (Cancelar) é inestimáveis.

Testes de unidade, como o NUnit, MSTest e outros sistemas exercer grande esforço para garantir que, quando gravados corretamente, testes não podem vazar os resultados de teste para a próxima. Se STM.NET atingir o status de produção, NUnit e MSTest podem refatorar seu código de execução caso de teste para usar transações STM para isolar os resultados de teste do outro, gerando uma reversão no final de cada método de teste e eliminando qualquer alteração que talvez foram geradas pelo teste. Ainda mais, qualquer teste que chama um método AtomicUnsupported será sinalizado no tempo de execução de teste como um erro, em vez de vazar silenciosamente o teste resulta alguma mídia fora do ambiente de teste (como para disco ou banco de dados).

STM.NET também pode ser usado na implementação de propriedade do objeto de domínio. Embora a maioria dos objetos de domínio têm bastante simples propriedades, o atribui a um campo ou retornar o valor do campo, propriedades mais complexas que têm várias etapas algoritmos corre o risco de vários threads, obtendo atualizações parciais (se outro thread chama a propriedade durante seu conjunto) ou atualizações fantasmas (caso outro thread chama a propriedade durante seu conjunto, e a atualização original é eventualmente descartada devido a um erro de validação de alguma forma).

Ainda mais interessante, pesquisadores fora da Microsoft estão procurando em estendendo as transações em hardware, de modo que um dia, atualizar o campo de um objeto ou uma variável local pode ser uma transação protegida no nível do hardware pela memória chip, tornando a transação blindingly rápido em comparação para métodos atuais.

No entanto, assim como acontece com Axum, Microsoft depende seus comentários para determinar se essa tecnologia é pena buscando e productizing, portanto, se você encontrar essa idéia empolgante ou interessantes ou que está faltando algo importante para a prática de codificação, Don hesite em que eles saibam.

Ted Neward é uma entidade com Neward and Associates, uma empresa independente especializado em sistemas empresariais .NET e Java. Ele escreveu vários livros, é um Microsoft MVP Architect, palestrante da INETA e instrutor da PluralSight. Ted pelo ted@tedneward.com , ou ler seu blog em <blogs.tedneward.com> .

Graças aos seguintes especialistas técnicos para revisar este artigo: Dave Detlefs e Dana Groff