October 25, 2009

Using Oracle Membership Provider in a Transaction

ASP.NET membership providers are nice framework for managing users and roles in ASP.NET Web applications but they have a strong weakness: they do not support transactions.

Why We Need Transactions During User Registration?

We may need to use transactions for example when we want to register new user account, assign few roles to it and configure some other tables for the new user, e.g. a table keeping user’s postal address and phone number. In this case if user registration fails for some reason and we are not in a transaction, the user could be partially registered and the database could become in inconsistent state. Imagine that during the registeration of new user called “peter” his address it too long to fit in the corresponding table column. The user registration will fail but the user will be partially registered and when Peter try to register again with a shorter address his preffered username “peter” will no longer be available. This is called “partially registered user”. Obviously we need to perform the entire user registration process in a transaction to avoid partially registered users, right?

Standard ASP.NET Membership Providers Do Not Support Transactions

To avoid incorrect behaviour during the user registration process described above we need to use transactions. We have two options:

  • Traditional ADO.NET transactions.
  • Using TransactionScope based transactions.

Standard ADO.NET Transactions

Using the traditional transactions from ASP.NET is not directly possible with ASP.NET membership providers because each operation they provide is supposed to open a new (their own) database connection with separate autonomous transaction. You cannot pass an open database connection and already started transaction as parameter to Membership.CreateUser(…), at least with the latest Oracle providers (ODP.NET 11.1.7.20). The membership provider will always establish a new database transaction and will register the user in separate database session and transaction.

TransactionScope and Distributed Transactions with Oracle

Using TransactionScope could potentially solve the problem but it will cause use of a distributed transaction (one transaction for your database connection and another transaction for the connection that the membership provider internally opens). This is a little bit tricky with the latest Oracle 11g Data Providers for .NET (ODP.NET). First you need to configure the connection parameters in a specific way (see the ODP.NET documentation). Second you need to install and run a special service called OracleMTSRecoveryService (which failed to install on 2 of my 3 testing environments with freshly installed Windows). Third, the Microsoft Dictributed Transaction Coordinator (MSDTC) should be running to handle the two-phase commits. Last, but very important problem is that distributed transactions just do not work with some combinations of Oracle database, Oracle Client and ODP.NET (I don’t remember the exact versions but some combinations just fail with an internal Oracle.DataAccess unmanaged exception). After few hours of testing TransactionScope and distributed transactions with Oracle database on various environments and reading lost of negative comments in the community forums I concluded that using distributed transactions with Oracle in tricky and I prefer to avoid it.

Hacking the Oracle ASP.NET Membership Provider

Due to the problems with the distributed transactions described above I decided to extend the Oracle.Web.dll library that implements the Oracle membership provider, Role provider, SiteMap provider, etc. with functionality allowing to pass an open database connection with an associated active transaction to all major operations (e.g. CreateUser, DeleteUser, etc.). What I did was to decompile the Oracle.Web.dll with .NET Reflector and its plugin called Reflector.FileDisassembler and obtain C# source code and Visual Studio 2008 project. The provider was not obfuscated and the bugs introduced during the compilation were fixable in few minutes (decompilation always is imperfect and the code is uncompilable). Adding additional parameter to all major provider functionality could take an hour or so and you can compile the Oracle.Web.dll library for x86 or x64 platforms. Note that Oracle.Web.dll is platform independed but uses Oracle.DataAccess.dll which has unmanaged code and is platform specific (32-bit or 64-bit).

The final result was my libraries called Extended.Oracle.Web.dll and Extended.Oracle.Web-x64.dll which extend the standard Oracle Membership provider (comming with ODP.NET) with ability to provide an open database connection when using the provider functionality. Using such functionality is simple:

try
{
  // Start database transaction (I use NHibernate but you could use ADO.NET instead)
  NHibernateSessionManager.Instance.BeginTran();

  // Persits the address first
  Address address = new Address(...);
  AddressDAO.Save(address);

  // Persits the user account
  OracleMembershipProvider membershipProvider = (OracleMembershipProvider) Membership.Provider;
  OracleConnection dbConnection = (OracleConnection)NHibernateSessionManager.Instance.GetSession().Connection;
  user = membershipProvider.CreateUser(profile.Username, profile.Password, profile.Email, dbConnection);

  // Assign roles to the user
  OracleRoleProvider roleProvider = (OracleRoleProvider)Roles.Provider;
  foreach (string role in new string[]{"Login", "Insurances", "Reports"})
  {
    roleProvider.AddUsersToRoles(new string[]{user.UserName}, new string[]{role}, dbConnection);
  }

  // Commit the transaction (if the entire user registration is successfull)
  NHibernateSessionManager.Instance.CommitTran();
}
catch (Exception ex)
{
  // Something failed during the registration process -> abort transaction
  NHibernateSessionManager.Instance.RollbackTran();
}

Finally we have transactions with the Oracle membership provider but without distributed transactions. Happy hacking!

P.S. I will not provide the modified x86 and x64 versions of Oracle.Web.dll and Oracle.DataAccess.dll because I believe that decompiling and redistributing non-open-source software from Oracle is “a little bit illegal” and I did the above decompilations just for training purposes and experiments (until the opposite is proven).

Tags: , , , , , , , , ,

1 Comment »

  1. Is very quick they will disappear at boundless yellow-colored sand in, be buried by a new built-up sand, until Huang Sha’s reasonable breezes suddenly and violently again overlord among states the entire sky, world’s imitating a Buddha has already become their worlds. But, under the complete violence, always the one who definitely have to humblely resist, can always completely withstand. Don’t. pull virtuous support [url=http://www.cheapchristianlouboutinhome.com/]cheap christian louboutin shoes[/url] the knot of needing a red of boundary, guard a girl at the side of body absolutely, a the silk breeze and a grain of sands each of the slightest can not ooze in to. He hopes the good breeze wreaks havoc with sand of the sky, tiny sigh a, unavoidably some regretses within heart, fix the sorcery to do the lifetime, in the great universe Wei dint ahead, he only can guard several individuals.

    The Xiao boon loudly shouts a way. He pensively and manually , spares no effort associated with in multiple layers take out to open a new sand, the wheat Ge strolling to him nearby along with does some help along. [I also come to help! ]The rice reaches to convey to leap [url=http://www.cheapchristianlouboutinhome.com/]christian louboutin[/url] from your ground and ran towards wheat Ge and this Xiao boon nearby. Along with more and more people or oneself the underside climbed out, or was come by the extrication from the sand of, example in the line that join to save a personnel to understand belonging to the all momentary. For a long moment after, be this sand dune drive public with one thought process join force of turn over new a moment of, supplies, personnel, even is corpses most of 11 of be place at sand up.

    pull virtuous assurance, obviously let the feeling comfy of Xiao boon settle a lot, he said: [That put. to the trouble grasp! ] The night check out keeps on being steadily deep, the night of wasteland is more getting chiller. Don’t know when your light of fire in the encampment have already quietly place, when the owners all have previously got into dreamland. This time, the sand [url=http://www.cheapchristianlouboutinhome.com/]christian louboutin[/url] grain connected with ground is suddenly very tiny turbulent for quite a while, whether this means that there is finally action in lifeless atmosphere desert. Over there darkly cover with belonging to the desert, under the night view of that hush, see in the owner sound like all have already fallen asleep, that fan Man the particular empty not known omen seem and fulfill around the desert.

    Read More:
    http://www.cheapchristianlouboutinhome.com/

    Comment by hofNopesharee — January 31, 2012 @ 15:06

RSS feed for comments on this post. TrackBack URL

Leave a comment