ASP.NET 2.0 and SQLServer 2000 Transactions

The new ADO.NET 2.0 and it's typed datasets and table adapters are very useful tools for creating a DAL in you application. Still when working with SQLServer 2000 implementing transactions is a bit tricky.

You can use TransactionScope but is seems to be designed for SQLServer 2005 as it will promote all transactions to distributed on SQLServer 2000 witch is a performance problem but also a bigger problem if your hosting provider does not provide distributed transactions. I've found a few solutions on the net some using reflection some using partial classes to add a method to the table adapter. Since i don't like using reflection unless i absolutely have to I've come up with a solution using partial classes but trying to minimize the code you have to write for each table adapter and also trying to make is less error prone.

The new ADO.NET 2.0 and it's typed datasets and table adapters are very useful tools for creating a DAL in you application. Still when working with SQLServer 2000 implementing transactions is a bit tricky.

First we define an interface witch the table adapters will implement:

1 public interface ITransactionable
2 {
3   SqlConnection SqlConnection {get;set;}
4   SqlCommand[] Commands {get;}
5 }

Now define a helper class that will manage all transaction operations.

 1 public class TransactionHelper
 2 {
 3   public static SqlTransaction BeginTransaction(ITransactionable adapter)
 4   {
 5     return BeginTransaction(adapter,IsolationLevel.ReadUncommitted);
 6   }
 7 
 8   public static SqlTransaction BeginTransaction(ITransactionable adapter, IsolationLevel lvl)
 9   {
10     SqlConnection con = adapter.SqlConnection;
11     if (con.State == ConnectionState.Closed)
12     con.Open();
13     SqlTransaction trans = con.BeginTransaction(lvl);
14     SetTransaction(adapter, trans);
15     return trans;
16   }
17   
18   public static void SetTransaction(ITransactionable adapter, SqlTransaction trans)
19   {
20     foreach (SqlCommand com in adapter.Commands)
21     com.Transaction = trans;
22     adapter.SqlConnection = trans.Connection;
23   }
24 }

Now for each table adapter that we need to use transactions:

1 public partial class DemoTableAdapter : ITransactionable
2 {
3   public SqlConnection SqlConnection { get { return Connection; } set { Connection = value; } }
4   public SqlCommand[] Commands { get { return CommandCollection; } }
5 }

As you can see the code needed for each table adapter is minimal and only requires copy-pasting and changing the name of the class. If c# would support c-style macros this could be reduced to a single line of code. To use the TransactionHelper class:

 1 ....
 2 SqlTransaction transaction=null;
 3 try{
 4   using(DemoTableAdapter adapter = new DemoTableAdapter())
 5   {
 6     transaction = TransactionHelper.BeginTransaction(adapter);
 7   .... operations with adapter ....
 8   }
 9   using(OtherTableAdapter adapter = new OtherTableAdapter ())
10   {
11     TransactionHelper.SetTransaction(adapter,transaction);
12   .... operations with adapter ....
13   }
14   transaction.Commit();
15 }
16 catch(Exception x)
17 {
18   transaction.Rollback();
19   ...handle error....
20 }
21 finally 
22 {
23   transaction.Dispose();
24 }

Hope it helps.

Windows Integration

Here is a preview of what you can do if you have a windows machine somewhere.

My Desktop

Flash7 with native FreeBSD browsers

Finally the linux-flash7 plugin works with native firefox. If it's not working for you this may help.

Update

With the nspluginwrapper port this
post
may be more usefull. The if you still have problems you may try the tips below.

Step By Step HOWTO

  1. Use cvsup or portsnap to update your ports tree
  2. install www/linuxpluginwrapper
  3. copy libflashplayer.so and flashplayer.xpt from distfiles/flashplugin/7.0r68/installflashplayer7linux.tar.gz to /usr/local/lib/browser_plugins
  4. Fireup firefox or opera and test

If in the future the dependency on the linux emulation layer is removed from linux-flash7 port it will be ok to install the port as you would normally do, but until then i prefer to manually unpack the two files instead of installing the hole linux-base port(s) witch is not needed anyway for the plugin to work.

If it works congratulations, if firefox crashes and opera displays just an empty box ... read on.

Fixing Plugin Crash

Here there are two things to try. (the first one is recommended)

  1. edit /etc/X11/xorg.conf and disable the Composite extension and set the ColorDepth to 24
  2. edit /usr/local/bin/firefox and add export XLIB_SKIP_ARGB_VISUALS=1 in the beginning of the file

I've noticed that opera still has some trouble working with the plugin and as a fix I've done a small change to the linuxpluginwrapper port. In compat_linux/linux_ioctl.c I've changed the default switch branch from:

1 default:
2     errno = ENOSYS;
3     ret   = -1;
4     dprintf("ioctl(fd=%d, request=%08X(on Linux), ...) = %d / ERRNO = %d", d, l_request, ret, errno);
5     break;

to

1 default:
2      ret= _ioctl(d,l_request,va_arg(ap,int*)); 
3      break;

After this change the plugin works fine but sometimes you need to reload the page for opera to display the flash content.

References

Information on fixing the crash was gathered from:

To be continued

Now that I've learned this i really have a good feeling about linux-flash9 and native browsers. I haven't tested yet but i guess the fix for the crashes works also for linux-flash9 with linu-firefox and linux-opera.

KDevelop - KDevTrollProject Problem

After updating kde to 3.5.6 and kdevelop to 3.4.0_1 ( around 15.03.2007 ) kdevelop failed to open qmake based projects. The error was "Error creating project management plugin KDevTrollProject".

Update

On 23.03.2007 a fix has been committed to the kdevelop port so if you encounter this problem it's better to update the ports tree and recompile kdevelop.

Finding why

It took me a few houers to find out that the problem was an undefined reference to a symbol in /usr/local/lib/libkdevqmakeparser.so. The symbol was QMake::Lexer. Grepping to kdevelop sources i found that the libkdevqmakeparser is build in buildtools/lib/parsers/qmake. There i found that qmake_lex.cpp was not compiled and linked to the library.

Quick Fix

Below are the command lines to build qmake_lex.cpp and relink libkdevqmakeparser.so

The fix_lex.sh file:

#!/bin/sh
if /bin/sh /usr/local/bin/libtool --silent --tag=CXX --mode=compile c++ -DHAVE_CONFIG_H  -I. -I. -I../../../.. -I../../../../lib/interfaces  -I../../../../lib/interfaces/extensions -I../../../../lib/util -I../../../../lib/widgets/propeditor  -I/usr/local/include -I/usr/X11R6/include  -I/usr/local/include  -D_THREAD_SAFE -pthread -DQT_THREAD_SUPPORT   -I/usr/local/include -I/usr/local/include  -I/usr/X11R6/include -D_GETOPT_H -D_THREAD_SAFE   -Wno-long-long -Wundef -Wall -W -Wpointer-arith -DNDEBUG -DNO_DEBUG -O2 -O2 -fno-strict-aliasing -pipe -Wno-non-virtual-dtor -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION  -MT qmake_lex.lo -MD -MP -MF ".deps/qmake_lex.Tpo" -c -o qmake_lex.lo qmake_lex.cpp;  then mv -f ".deps/qmake_lex.Tpo" ".deps/qmake_lex.Plo"; else rm -f ".deps/qmake_lex.Tpo"; exit 1; fi
/bin/sh /usr/local/bin/libtool --silent --tag=CXX --mode=link c++   -Wno-long-long -Wundef -Wall -W -Wpointer-arith -DNDEBUG -DNO_DEBUG -O2 -O2 -fno-strict-aliasing -pipe -Wno-non-virtual-dtor -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION    -o libkdevqmakeparser.la -rpath /usr/local/lib -no-undefined  -L/usr/local/lib -L/usr/X11R6/lib   -D_THREAD_SAFE -pthread  -L/usr/local/lib -lkio qmakeast.lo qmakedriver.lo  qmake_yacc.lo qmake_lex.lo qmakeastvisitor.lo  -Wl,-export-dynamic -L/usr/local/lib -L/usr/X11R6/lib -ljpeg  -L/usr/X11R6/lib
cd /usr/ports/devel/kdevelop
make extract patch configure
cd work/kdevelop-3.4.0/buildtools/lib/parsers/qmake
sh fix_lex.sh
cp .libs/libkdevqmakeparser.so.0 /usr/local/lib/

Conclusion

I somehow have the impression that I'm the only one having this problem since i haven't seen any reports on the mailing lists. It may be some bad combination of autotools/libtools. If I'm the only one having this problem then it's not worth investing more time in a proper fix. If other users will report this problem then probably a patch to add the qmake_lex.cpp file to the Makefile with appropriate rules may be needed. My experience with autotools and handwritten Makefiles is close to zero (and i intend to keep it that way) but i guess the kde folks will have no problem fixing this once the problem i known.

If someone else experiences this problem please leave a comment or a post a message on the freebsd mailing list