Welcome to MSDN Blogs Sign in | Join | Help

Intro for Microsoft Azure .Net Service Bus

Clemens Vasters gives a great introduction to Microsoft Azure .Net Service Bus and its 4 feature areas: Naming, Registry, Connectivity, and Eventing. Find it at http://vasters.com/clemensv/PermaLink,guid,92d78bee-2cfd-4a29-95ab-c5abb9b905e7.aspx

Posted by florinlazar | 1 Comments

Atbroker.exe application error - CTRL-ALT-END in a remote session

I use remote desktop daily. The Atbroker.exe application error followed by black screen seemed to be gone for a while. Now it is back. The only solution that I know of and which works most of the times is "CTRL-ALT-END" (the equivalent of “CTRL-ALT-DEL” for remote sessions) followed by ESC. When it doesn’t work, I need to log in with another user and kill the session with the issue or reboot the box – nasty.

Posted by florinlazar | 1 Comments

When not to use transactions and where you can't use transactions

Transactions are great when everyone plays in. You group a set of activities together under a transaction and you start executing them. If anything bad happens along the way or something doesn't go as planned, invoke rollback and all is taking care of automatically by the infrastructure: everything is undone and the app returns to the state before the transaction started; recovery and consistency is a piece of cake with nothing to worry about.

 

But...

 

I can't really use transactions for long running sequences of activities. I mean, technically is possible, but the app will not scale anymore. Imagine starting the transaction today, updating databases and doing transactional work for a few days; add to that a few human interventions (when user input is required) and make it a few more days longer and only after that commit the transaction. What just happened? For those number of days, the transactional work kept all the resources that it touched in a locked state waiting for the commit (or rollback) decision. All these resources could not be used by anybody else (with various degrees of freedom depending on your isolation level) for that many days. Transactions are really meant for short lived work.

 

Another aspect, partial rollback - the ability to rollback some work in the case of an event, but let the rest of the work that executed so far to continue towards a possible commit. This is not possible today with how transactions are implemented: have at least one little piece of work or resource declare itself in error and the whole transaction will rollback, no exceptions allowed.

 

And then, maybe the most major aspect, not everything participates in a transaction. It can be a resource, it can be an action that can't rollback. Implementing resources that are transactional is not trivial, meeting all the ACID properties is hard. Or in some cases, it just doesn't make sense to make something transactional, like sending an email. What to rollback there?. Chase the internet to catch the email before it reaches ones inbox, and if it got to the inbox, tell the reader to forget it?

 

In all these cases, something else needs to be used in combination with short lived transactions. That means that you need to provide code that un-does/cancels/compensates the work that was already done. You need to write most of the "undo" code since the rules need to be more relaxed than with transactions. The compensation logic varies depending on the application logic at that given time. In the transactions world, the ACID requirements govern everything and there are always only two states: an initial state before transaction and a state after the transaction commits; rollback will always move the app back to the initial state. With compensation, the number of consistency states depends on the app and are defined by the app.

 

Support for compensation exists today in Biztalk Server and Windows Workflow.

MSDTC and COM+ Configuration Tool in Vista

To access the MSDTC and COM+ configuration tool in Windows Vista, also known as Component Services MMC, you have the following options:

1.       Run “dcomcnfg”

2.       Or run: %SystemRoot%\System32\comexp.msc

3.       Or if you prefer, you can add a shortcut to %SystemRoot%\System32\comexp.msc in Control Panel

 

If you have UAC on and you want to do 3, first make a shortcut for %SystemRoot%\System32\comexp.msc on your Desktop and then move it to Control Panel.

Posted by florinlazar | 0 Comments
Filed under:

Exception Handling without catch(Exception)

The design guidelines for exception handling are quite clear on avoiding “catch all” and/or avoiding catching exceptions you can’t handle. But there are cases when you really need to know if the try block completed successfully or not, and possibly take some action.

 

One way one could achieve this without breaking the guideline is to set a flag at the end of the try block and then query it inside finally:

 

bool workCompleted = false;

try

{

 

    DoSomething();

    DoSomethingMore();

    workCompleted = true;

}

finally

{

    if (!workCompleted)

    {

        Console.WriteLine("record that the work failed");

    }

}

 

Posted by florinlazar | 2 Comments
Filed under:

Working with CMD and Long Path Names

I like using the command prompt for a lot of things and working with long (or very long) path names is something that is common these days.

Fortunately, you can customize cmd by using "prompt". Do a “prompt /?” in a command window  to see all the options.

I like it simple and I use: “PROMPT=$p$_$+$g”. This gives:

 

C:\Windows\System32\Msdtc\Trace

> 

 

To persist it, set it as an environment variable.

Posted by florinlazar | 0 Comments
Filed under:

How to Use System.Data with System.Transactions and Maintain Atomicity and Data Consistency

The Bug

I call it a bug. Initially I was persuaded to believe it was a feature; later I was "convinced" that it is now a matter of app compat and it can't be changed anymore.

 

Let’s look at the following code:

 

SqlConnection connection1 = new SqlConnection(connectionString);

 

using(TransactionScope txScope = new TransactionScope())

{

    connection1.Open();

 

    SqlCommand command1 = new SqlCommand(commandString1, connection1);

    command1.ExecuteNonQuery();

 

    SqlCommand command2 = new SqlCommand(commandString2, connection1);

    command2.ExecuteNonQuery();

 

    txScope.Complete();

}

 

 

What are your expectations from this code? I’m sure you are saying that both commands will execute with success or none will execute, for instance if command1 succeeds and command2 fails and throws, the transaction rollbacks and command1 is undone. Right?

 

Let’s add more data to the equation: transactions can abort at any time due to various reasons, most common one being timeouts. Let’s imagine that the transaction timeout is 30 seconds. Then, let’s imagine that command1 takes 29.(9) seconds to execute. This means that the transaction aborts immediately after that. Let’s imagine that it aborts before command2 starts executing. Now, what are the expectations here? Well, transaction aborts and then command1 is undone and everything goes back to the state before the transaction was started.

Unfortunately, by using the defaults for System.Data this is not what happens. What really happens is:

-          command1 is undone

-          command2 is executed outside the transaction

There is no typo there, command2 executes even if the transaction aborted. In other words, if one expected atomicity for the code inside TransactionScope, the code just corrupted the data due to the partial rollback.

 

The “Feature”

 Apparently the following code is common:

 

SqlConnection connection1 = new SqlConnection(connectionString);

 

using(TransactionScope txScope = new TransactionScope())

{

    connection1.Open();

 

    SqlCommand command1 = new SqlCommand(commandString1, connection1);

    command1.ExecuteNonQuery();

 

    SqlCommand command2 = new SqlCommand(commandString2, connection1);

    command2.ExecuteNonQuery();

 

    txScope.Complete();

}

 

SqlCommand command3 = new SqlCommand(commandString3, connection1);

command3.ExecuteNonQuery();

 

In other words, the “feature” allows the use of the connection in auto-commit mode after it was previously used in a transaction. The connection automatically unbinds from the transaction when the transaction completes (either abort or commit) and becomes an auto-commit non-transacted connection.

 

The App Compat Issue

Now that we know that the automatic unbind can lead to data corruption, changing it to not unbind automatically will make the code for command3 to fail to execute, since the connection1 is trying to run a command in a transaction that completed. Thus, if the code is indeed common, changing the behavior of the connection will indeed break existing apps.

 

The Solution

The solution implemented by System.Data in “Orcas” is to pass a new keyword to the connection string called “Transaction Binding” and give it the value of “Explicit Binding” to disable the auto-unbind. This will cause command2 to try to execute under the same transaction as command1, even after the abort occurred. See ConnectionString and Integration with Transactions for details.

The following thread might also be useful: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3055387&SiteID=1

 

Hopefully, the default behavior will change to explicit unbind in the future releases (non-SP) of .Net Framework.

Posted by florinlazar | 4 Comments

Limitation of TransactionScope (and using)

If you read the documentation for TransactionScope, you will find: "If no exception occurs within the transaction scope […], then the transaction in which the scope participates is allowed to proceed. If an exception does occur within the transaction scope, the transaction in which it participates will be rolled back." Later the doc says: “When your application completes all work it wants to perform in a transaction, you should call the Complete method only once to inform that transaction manager that it is acceptable to commit the transaction. Failing to call this method aborts the transaction.”

 

OK, so how about this code:

 

using(TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) {

    // do transactional work

 

    ts.Complete();

    throw new Exception();

}

 

What happens to the transaction after executing this code? Take a guess. If we follow the doc, the transaction roll backs, right? Well, the transaction actually commits – try it out!

 

Let’s see what happens by “unpacking” the using statement:

     

TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew);

try {

    // do transactional work

 

    ts.Complete();

    throw new Exception();

}

finally {

    ts.Dispose();

}

 

In the Dispose of TransactionScope something similar to the following pseudo-code happens:

 

       if Complete was called {

              Transaction.Commit();

}

else {

       Transaction.Rollback();

}
 

The limitation really comes from the fact that at Dispose time in finally, the using construct doesn’t offer any information about completion of its body with exception or not. That is why the Transaction.Complete was invented and that is why the documentation for Complete says: “It is very good practice to put the call as the last statement in the using block.” Complete was invented to detect exceptions, i.e. if an exception occurs, Complete will not get called – but this work only if one follows the guideline to put Complete as the last statement. Doing any work after Complete was called is asking for trouble and possible data corruption. 

 

If you want to be on the safe side, use my transacted construct which doesn’t have these issues. It follows a simple rule: if an exception is thrown, the transaction aborts, otherwise it commits.

Posted by florinlazar | 0 Comments
Filed under: ,

Avoiding Transaction Promotion with Multiple Connections - Improvements in System.Data and SQL Server 2008

Great news! The new updates added to System.Data and SQL Server 2008 finally allow multiple Open/Close connections to the same SQL Server without promoting the transaction to MSDTC.

This was by far the most requested feature for the System.Transactions/System.Data/SQL Server combination.

There is no more the need to write workarounds like ConnectionScope to avoid promotions.

Now I can write as many Open/Close, Open/Close as I need to, without worrying about promotion:

transacted(()=>
{
   using (SqlConnection connection1 = new SqlConnection(connectionString))
   {
      Connection1.Open();

      SqlCommand command1 = new SqlCommand(commandString1, connection1);
      command1.ExecuteNonQuery();

      SqlCommand command2 = new SqlCommand(commandString2, connection1);
      command2.ExecuteNonQuery();

      connection1.Close();
   }

   ...

   using (SqlConnection connection2 = new SqlConnection(connectionString))
   {
      Connection2.Open();

      SqlCommand command1 = new SqlCommand(commandString1, connection2);
      command1.ExecuteNonQuery();

      SqlCommand command2 = new SqlCommand(commandString2, connection2);
      command2.ExecuteNonQuery();

      connection2.Close();
   }
});

More details on the updates at the ADO.Net team blog.

A Simpler TransactionScope

In .Net 3.5 I can write a transactional code block as follows:

transacted(()=>
{
   using (SqlConnection connection = new SqlConnection(connectionString))
   {
      connection.Open();

      SqlCommand command1 = new SqlCommand(commandString1, connection);
      command1.ExecuteNonQuery();

      SqlCommand command2 = new SqlCommand(commandString2, connection);
      command2.ExecuteNonQuery();
   }
});

No need for using and no need to remember to call Complete at the end of the block.

To enable this I need to write just a few lines of code:

delegate void TransactedCodeDelegate();
void transacted(TransactedCodeDelegate txCode)
{
   using (TransactionScope ts = new TransactionScope())
   {
      txCode();
      ts.Complete();
   }
}
Posted by florinlazar | 3 Comments
Filed under:

Flowing or propagating transactions in .Net

System.Transactions transactions are bounded to the appdomain. Which means that if you make in-appdomain calls from inside a TransactionScope, those calls will share the transaction. This also means that if you need to make a call outside the current appdomain, or outside the process, you will need to "flow" the transaction.

To flow a System.Transactions transaction, there are a few options:

a. if you are using serialization
 

//sender code
using(TransactionScope ts = new TransactionScope())
{
  RemoteCallUsingSerialization(Transaction.Current, other parameter); // this is the call to other appdomain/process
  // notice I added a new parameter of type System.Transactions.Transaction  

  ts.Complete();
}

//destination code
void RemoteCallUsingSerialization(System.Transactions.Transaction tx, other parameter)
{
  using(TransactionScope ts2 = new TransactionsScope(tx))
  {
   // access transactional resourses like a database; this code will execute as part of the same transaction
   ts2.Complete();
  }
}

b. if you are not using serialization
 

//sender code
using(TransactionScope ts = new TransactionScope())
{  
  RemoteCall(TransactionInterop.GetTransmitterPropagationToken(Transaction.Current), other parameter); // this is the remote call
  // notice I added a new parameter of type byte[]  

  ts.Complete();
}

//destination code
void RemoteCall(byte[] tx, other parameter)
{
  using(TransactionScope ts2 = new TransactionsScope(TransactionInterop.GetTransactionFromTransmitterPropagationToken(tx)))
  {
   // access transactional resourses like a database;
   // this code will execute as part of the same transaction
   ts2.Complete();
  }
}

c. if .Net 3.0 or higher is an option, you can use WCF and its support for transactions using attributes: http://msdn2.microsoft.com/en-us/library/aa347993.aspx

Remark: When the transaction is flown outside the current appdomain, it will get upgraded to a distributed transaction (or MSDTC transaction).

If you are not using .Net, see http://blogs.msdn.com/florinlazar/archive/2004/10/02/236965.aspx for propagating transactions in C++.

TIP is now deprecated

TIP is getting deprecated - see the note at http://msdn2.microsoft.com/en-us/library/ms679484(VS.85).aspx
If the native OleTx protocol used by MSDTC and System.Transactions is not friendly enough for your firewall, you should consider the WS-AtomicTransactions protocol provided through Windows Communication Foundation in .Net Framework 3.0 and higher: http://msdn2.microsoft.com/en-us/library/ms730266.aspx
Posted by florinlazar | 0 Comments
Filed under:

MSDN Magazine Article on Transactional File System

Jason Olson describes the Transactional NTFS and how you can take advantage of it in your applications: http://msdn.microsoft.com/msdnmag/issues/07/07/NTFS/default.aspx

Posted by florinlazar | 0 Comments
Filed under:

WCF in Romania

These days I'm in Romania with a tour at 3 universities (in Bucharest, Cluj and Iasi) talking about Windows Communication Foundation, distributed systems and web services. Adi Oltean is also talking about storage technologies in Windows.

So far the seminars were received really well and we made a lot of friends. I'm really pleased to be able to contribute to the adoption of WCF and to demonstrate the amazing value and power of WCF with its productivity, interoperability and extensibility features.

 More details at http://reg.studentclub.ro/RegisterForEvent.aspx?idEveniment=55 (in romanian).

 I would like to thank Todi Pruteanu for organizing these events.

Posted by florinlazar | 3 Comments
Filed under:

"Orcas" March 07 CTP: Support for OASIS WS-AT 1.1 and WS-Coord 1.1

In the "Orcas" March 2007 CTP for Visual Studio and .Net, Windows Communication Foundation brings support for OASIS specifications WS-AtomicTransaction 1.1 and WS-Coordination 1.1. WCF will have side-by-side support with the 1.0 versions of these specs.

To use the new version of WS-AT, you can specify the new WS2007HttpBinding, or, if you already use the NetTcpBinding, you can set the TransactionProtocol to WSAtomicTransactions11.

Posted by florinlazar | 3 Comments
Filed under:
More Posts Next page »
 
Page view tracker