programming4us
programming4us
DATABASE

SQL Server 2012 : Distributed Transactions (part 3) - Distributed Transactions in the .NET Framework - Writing Your Own Resource Manager

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

4.1 Writing Your Own Resource Manager

It is only reasonable to expect that because databases are the most critical part of the architecture (at least to database developers and administrators!), they have had fantastic transactional support for a long time. But don’t you want your other, nondatabase operations to be transactional as well if they also could benefit from transactional behavior?

Let’s consider the simple operation of setting a value to an integer and wrapping that as a part of a transaction, as shown in the following code snippet. The first question is: How do you set a value for an integer?

int myInt;
myInt = 10;

Unfortunately, wrapping this code in a TransactionScope won’t make it transactional. This is because System.Int32 is not smart enough to understand that it is being wrapped inside a TransactionScope and that it should auto-enlist within a running transaction. This is probably a good thing, because in the event of a rollback, to perform a graceful recovery, System.Int32 would have to maintain a previous version. You probably wouldn’t want to pay this overhead for all your integers. So you need to write a class that lets you maintain enough history in the event of a rollback. This class should also be able to interact with a TM and listen for various two-phase commit notifications. To do so, this class, or the RM you are writing, must implement the IEnlistmentNotification interface. This interface requires you to implement certain methods that are called at the appropriate points in time by the TC during the two phases of a two-phase commit process.

Here are the methods that IEnlistmentNotification requires you to implement:

  • Commit Notifies the RM that the transaction has been committed. The RM then makes the changes permanent.

  • Rollback Notifies the RM that the transaction has been rolled back. The RM then reverts to the previous stable state.

  • Prepare Called during the first (prepare) phase of a distributed transaction—when the TM asks the participants whether they are ready to commit. If the TM receives a successful notification from each participating RM, it calls the Commit methods.

  • InDoubt Notifies the RMs if the TM loses contact with one or more participants in the transaction. In this situation, the status of the transaction is unknown, and the application logic must decide whether to revert to the previous consistent state or remain in an inconsistent state.

Example 3 puts all of these concepts into actual code. It shows a full implementation of a volatile RM.

Example 3. Implementing your own resource manager.

public class VolatileRM : IEnlistmentNotification
{
private string _whoAmI = "";
public VolatileRM(string whoAmI)
{
this._whoAmI = whoAmI;
}

private int _memberValue = 0;
private int _oldMemberValue = 0;
public int MemberValue
{
get
{
return this._memberValue;
}

set
{
Transaction tran = Transaction.Current;
if (tran != null)
{
Console.WriteLine(
this._whoAmI + ": MemberValue setter - EnlistVolatile");
tran.EnlistVolatile(this, EnlistmentOptions.None);
}
this._oldMemberValue = this._memberValue;
this._memberValue = value;
}
}

#region IEnlistmentNotification Members

public void Commit(Enlistment enlistment)
{
Console.WriteLine(this._whoAmI + ": Commit");

// Clear out _oldMemberValue
this._oldMemberValue = 0;
enlistment.Done();
}

public void InDoubt(Enlistment enlistment)
{
Console.WriteLine(this._whoAmI + ": InDoubt");
enlistment.Done();
}

public void Prepare(PreparingEnlistment preparingEnlistment)
{
Console.WriteLine(this._whoAmI + ": Prepare");
preparingEnlistment.Prepared();
}

public void Rollback(Enlistment enlistment)
{
Console.WriteLine(this._whoAmI + ": Rollback");

// Restore previous state
this._memberValue = this._oldMemberValue;
this._oldMemberValue = 0;
enlistment.Done();
}

#endregion
}

Let’s examine this code more closely. At the very top is a class that implements IEnlistmentNotification. This signifies that your RM will receive notifications from the current transaction manager:

public class VolatileRM : IEnlistmentNotification

The code begins with a private string variable named _whoAmI and a constructor. This will help you analyze the chain of events when more than one RM is involved.

private string _whoAmI = "";
public VolatileRM(string whoAmI)
{
this._whoAmI = whoAmI;
}

Next, the code defines two class-level variables named _memberValue and _oldMemberValue, followed by a MemberValue property. The motivation for writing this class is the fact that System.Int32 is unable to interact with an RM or maintain historical values to roll back integers. The MemberValue property’s get accessor exposes _memberValue, and its set accessor assigns a new value to _memberValue and then enlists in the currently running transaction. The _oldMemberValue variable holds the historical value that will be used in the event of a rollback.

private int _memberValue = 0;
private int _oldMemberValue = 0;
public int MemberValue
{
get { return _memberValue; }
set
{
Transaction tran = Transaction.Current;
if (tran != null)
{
Console.WriteLine(
tran._whoAmI + ": MemberValue setter - EnlistVolatile");
tran.EnlistVolatile(this, EnlistmentOptions.None);
}
this._oldMemberValue = this._memberValue;
this._memberValue = value;
}
}

As you can see, the code first attempts to find the current transaction in the Transaction.Current variable, and then uses the EnlistVolatile method to enlist in the current transaction in a volatile manner. Volatile enlistment is sufficient for this example. If you were working with a durable resource, you would call the EnlistDurable method instead. Last, the code performs the logic of assigning the new value and preserving the old value.

With the class and its data set up, the rest of the details involve hooking up implementation so that you can enlist in a current running transaction with the RM and perform the appropriate actions based on the notifications received. This functionality is implemented in the four methods that the IEnlistmentNotification interface requires you to implement. The TM calls the appropriate methods (Commit, Rollback, Prepare, and InDoubt) for you and passes in a System.Transactions.Enlistment variable as a parameter. After successfully performing each step, you should call the enlistment.Done() method to indicate that this step has done its work.

The only exception to this rule is the Prepare method, which receives a special kind of Enlistment, a System.Transactions.PreparingEnlistment variable, as a parameter, which inherits from the System.Transactions.Enlistment class. PreparingEnlistment adds a few methods to Enlistment:

  • ForceRollBack() or ForceRollBack(Exception) Notifies the TM that an error has occurred and that the current participating RM wants to issue a rollback. You can specify your own exception if you want.

  • Prepared Notifies the TM that this RM has successfully finished doing its part of the transaction (the prepare phase of the two-phase commit process).

  • byte[] RecoveryInformation Used to specify information to the TM in the event of reenlistment to perform a graceful recovery (in situations such as the RM crashing). Alternatively, you can call the base class method Done to act as an innocent bystander and observe the transaction but not really participate in it. If you call Done in the prepare phase, the TM skips notifying the RM of the second (commit) phase of a two-phase notification process.

Other  
  •  Protecting SQL Server Data : TRANSPARENT DATA ENCRYPTION (part 6) - Reversing the Implementation of TDE
  •  Protecting SQL Server Data : TRANSPARENT DATA ENCRYPTION (part 5) - Verifying TDE - Verification through Backup and Recovery
  •  Protecting SQL Server Data : TRANSPARENT DATA ENCRYPTION (part 4) - Verifying TDE - Using Dm_Database_Encryption_Keys
  •  Protecting SQL Server Data : TRANSPARENT DATA ENCRYPTION (part 3) - Implementing TDE - The User Database
  •  Protecting SQL Server Data : TRANSPARENT DATA ENCRYPTION (part 2) - Implementing TDE - Backup before Proceeding , The Master Database
  •  Protecting SQL Server Data : TRANSPARENT DATA ENCRYPTION (part 1) - How TDE Works, Considerations when Implementing TDE
  •  SQL Server 2012 : Isolation Levels (part 2) - Repeatable Read Isolation Level,Snapshot Isolation Level, Isolation Levels in ADO.NET
  •  SQL Server 2012 : Isolation Levels (part 1) - Read Uncommitted Isolation Level, Read Committed Isolation Level
  •  SQL Server 2012 : Local Transaction Support in SQL Server (part 2) - Implicit Transaction Mode, Batch-Scoped Transaction Mode
  •  SQL Server 2012 : Local Transaction Support in SQL Server (part 1) - Explicit Transaction Mode
  •  
    Top 10
    Free Mobile And Desktop Apps For Accessing Restricted Websites
    MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
    TOYOTA CAMRY 2; 2.5 : Camry now more comely
    KIA SORENTO 2.2CRDi : Fuel-sipping slugger
    How To Setup, Password Protect & Encrypt Wireless Internet Connection
    Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
    Backup & Restore Game Progress From Any Game With SaveGameProgress
    Generate A Facebook Timeline Cover Using A Free App
    New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    - Messages forwarded by Outlook rule go nowhere
    - Create and Deploy Windows 7 Image
    - How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
    - Creating and using an unencrypted cookie in ASP.NET
    - Directories
    - Poor Performance on Sharepoint 2010 Server
    - SBS 2008 ~ The e-mail alias already exists...
    - Public to Private IP - DNS Changes
    - Send Email from Winform application
    - How to create a .mdb file from ms sql server database.......
    programming4us programming4us
    programming4us
     
     
    programming4us