Red de conocimiento informático - Conocimiento informático - ¿Cómo hacer que las variables ordinarias también admitan la reversión de transacciones?

¿Cómo hacer que las variables ordinarias también admitan la reversión de transacciones?

Una vez estaba hablando con alguien sobre negocios y qué tipo de recursos pueden ser recursos orientados a los negocios. Además de las bases de datos, colas de mensajes, sistemas de archivos transaccionales (TxF) y registros transaccionales (TxR) que utilizamos habitualmente, ¿qué otros recursos se pueden incluir directamente en la gestión del estado de las transacciones? Dije que si encapsulamos razonablemente los recursos correspondientes de acuerdo con las especificaciones del modelo de transacción .NET, en principio podemos convertir cualquier recurso programable en un recurso transaccional. En este artículo, utilizaré una programación simple para convertir una variable ordinaria en una variable que admita transacciones, de modo que el valor de la variable también pueda revertirse para garantizar la coherencia de los datos antes y después de la transacción. 1. ¿Qué son las variables transaccionales? Las variables transaccionales mencionadas en este artículo se refieren a variables: antes de que comience la transacción, se guardará el valor inicial de la variable en la transacción solo se puede realizar después de que la transacción se realice correctamente; enviado Solo entonces se asignará realmente el valor a la variable; si la transacción se cancela y resulta en una reversión, el valor de la variable se restaurará al estado anterior a que comenzara la transacción. La descripción anterior de las variables transaccionales se puede reflejar en el siguiente programa: a la variable v se le asigna un valor de 1 durante la inicialización. Luego inicie una transacción a través de TransactionScope e incluya las variables en la transacción. Asigne el valor a 2 dentro del alcance de la transacción, luego llame al método DoSomething y confirme la transacción. Si se produce una excepción durante la ejecución de DoSomething, se revertirá toda la transacción. Cuando se cancela y revierte toda la transacción, el valor de la variable v vuelve al estado anterior al inicio de la transacción, es decir, el valor es 1. 1: staticvoid Main(string[] args) 2: { 3: TransactionalVariablelt; intgt; v = new TransactionalVariablelt; intgt (1); { 8: Transaction.Current.EnlistPromotableSinglePhase(v); 9: v.Value = 2; 10: DoSomething(); 11: transactionScope.Complete(); .Assert(v.Value == 1); 17: } 2. Hable brevemente sobre el modelo de transacción System.Transactions. La naturaleza de las variables transaccionales ha quedado muy clara. La tarea fundamental ahora es cómo definir dicha variable transaccional. Escriba, es decir, el tipo TransactionalVariablelt;Tgt; en el programa de ejemplo anterior. Pero antes de eso, debemos mirar brevemente el modelo de transacción de System.Transactions. Para todos los participantes de la transacción, desempeñan aproximadamente los siguientes tres roles según sus funciones en cada etapa del ciclo de vida completo de la transacción: Aplicación, Servicio o Componente: representa el programa de usuario, o Un servicio o componente que lleva a cabo una determinada función; (RM: Resource Manager): representa un programa de software utilizado para administrar recursos transaccionales específicos, como una base de datos o cola (MSMQ), etc. (TM: Transaction Manager): representa el programa middleware que administra toda la transacción y Proporciona servicios básicos de control de transacciones para aplicaciones y administradores de recursos.

Con respecto al modelo de gestión de transacciones específico de System.Transactions, puede consultar mi artículo "Hablando sobre transacciones distribuidas Parte 2: Modelo de gestión de transacciones distribuidas basado en DTC [Parte 1]", que no se presentará aquí. Con todo, siempre que podamos escribir el "administrador de recursos" correspondiente para la variable, podemos incluirlo en System.Transactions.Transaction. En el sistema System.Transactions, escribir un administrador de transacciones es una cuestión muy simple. Una forma muy directa es implementar una interfaz como IPromotableSinglePhaseNotification. El tipo TransactionalVariablelt;Tgt; utilizado en el código de ejemplo se define de esta manera. 3. Defina TransactionalVariablelt; implementando la interfaz IPromotableSinglePhaseNotification. Antes de presentar en detalle la definición de TransactionalVariablelt; El siguiente fragmento de código refleja la definición de IPromotableSinglePhaseNotification: además de los miembros heredados de la interfaz principal, toda la interfaz IPromotableSinglePhaseNotification tiene 4 miembros de método. Se llamará al método Initialize cuando el recurso se incluya en la transacción para realizar algunas operaciones de inicialización. SinglePhaseCommit, Rollback y Promote se utilizan para notificar que las transacciones se están confirmando, revirtiendo y promoviendo. 1: publicinterface IPromotableSinglePhaseNotification: ITransactionPromoter 2: { 3: void Initialize(); 4: void Rollback(SinglePhaseEnlistment singlePhaseEnlistment); 5: void SinglePhaseCommit(SinglePhaseEnlistment singlePhaseEnlistment); (); 10: }TransactionalVariablelt; Tgt; implementa directamente la interfaz IPromotableSinglePhaseNotification. Las siguientes son todas las definiciones. TransactionalVariablelt;Tgt; define dos miembros de datos, el campo _originalValue y el atributo Valor representan el valor inicial y el valor actual de la variable.

Inicializar: asigna el valor actual al valor inicial, momento en el que ambos tienen el mismo valor. Rollback: asigna el valor inicial al valor actual y llama al método Abortado de SinglePhaseEnlistment para notificar la terminación de la transacción, lo que significa que cualquier las modificaciones a las variables durante la transacción se perderán; SinglePhaseCommit: asigne el valor actual al valor inicial y llame al método comprometido de SinglePhaseEnlistment para notificar la transacción de confirmación, lo que equivale a realizar oficialmente la modificación de la variable en la transacción. efectivo; Promocionar: Dado que solo pretendemos que nuestras variables transaccionales admitan transacciones locales, el escenario no brinda soporte para transacciones distribuidas, aquí se genera una excepción directamente 1: usando System.Transactions 2: espacio de nombres Artech.TransactionalObjects 3: { 4: publicclass; TransactionalVariablelt; Tgt;: IPromotableSinglePhaseNotification 5: { 6: privado T _originalValue; 7: público T Valor { get } 8: 9: ?0?2 10: public TransactionalVariable(T variable) 11: { 12: this.Value; = variable; 13: } 14: ?0?2 15: publicvoid Inicializar() 16: { 17: _originalValue = this.Value; } 19:?0?2 20: publicvoid Rollback(SinglePhaseEnlistment singlePhaseEnlistment) 21: { 22 : this.Value = _originalValue; 23: singlePhaseEnlistment.Aborted( ); 24: } 25:?0?2 26: publicvoid SinglePhaseCommit(SinglePhaseEnlistment singlePhaseEnlistment) 27: { 28: _originalValue = this.Value; 30: } 31:?0?2 32: publicbyte [] Promote() 33: { 34: thrownew TransactionException("TransactionalVariable solo admite transacciones locales."); En la implementación, no hay nada especial, solo a través de la implementación Almacenar en caché el valor inicial para que el valor pueda restaurarse a su estado anterior cuando se cancela la transacción. Puedes descargar el ejemplo aquí. Sin embargo, este ejemplo es sólo una simple demostración de simulación y tiene muchas deficiencias. Por ejemplo, el aislamiento de los cuatro atributos de las transacciones no se puede reflejar en TransactionalVariablelt;Tgt;.