Global Connection object?

  • Thread starter Thread starter Baranyi Peter
  • Start date Start date
B

Baranyi Peter

Hi,

in the old times (I mean before .NET) we had to use only one connection
object in our applicaiton, since the connection eats a lot of resources, and
it takes a long time to connect. Unfortunatelly I can not see any sample
where are more, than one form, and therefore I don't know how to keep only
one connect, what can be used allover the forms.

Any idea?

Thanks:

Peter
 
Hi Baranyi,

Just keep connection string somewhere, create connection instances just
before you need them and dispose them asap.
The pooling will keet the overhead minimal (while in multithreaded
application you'll actually gain performance).
 
Sure, there is nothing to stop you from creating and opening a persistent
connection in a Windows Forms using ADO.NET. No, this won't work with
ASP.NET applications.
It does save time because even the connection pool Open takes time to
execute. It also prevents you from leveraging server-side functionality that
you CAN use in ADO.NET. The problem is, it limits the number of users your
server can handle--from several hundred to several thousand or so.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________
 
William (Bill) Vaughn said:
Sure, there is nothing to stop you from creating and opening a persistent
connection in a Windows Forms using ADO.NET. No, this won't work with
ASP.NET applications.
It does save time because even the connection pool Open takes time to
execute. It also prevents you from leveraging server-side functionality
that you CAN use in ADO.NET. The problem is, it limits the number of users
your server can handle--from several hundred to several thousand or so.

--

And _how_ to do it is simple. Use a public variable in a module, just like
VB6. Or make it a "Shared" (static in C#) member of some class.

Or you can do something a little more fancy, along the lines of:

Imports System.Data

Class GlobalConnection
Private Shared con As SqlConnection
Private Shared tran As SqlTransaction
Public Shared Sub Connect(ByVal ConnectionString As String)
con = New SqlConnection(ConnectionString)
con.Open()
End Sub
Public Shared ReadOnly Property Connection()
Get
Return con
End Get
End Property
Public Shared ReadOnly Property Transaction() As SqlTransaction
Get
Return tran
End Get
End Property
Public Shared Sub BeginTransaction()
tran = con.BeginTransaction
End Sub
Public Shared Sub CommitTransaction()
tran.Commit()
tran = Nothing
End Sub
Public Shared Sub RollbackTransaction()
tran.Rollback()
tran = Nothing
End Sub

Public Shared Function CreateCommand(ByVal sql As String, _
ByVal ParamArray parameters()
As SqlParameter)

Static commandCache As New Hashtable

Dim cmd As SqlCommand
If commandCache.ContainsKey(sql) Then
cmd = DirectCast(commandCache(sql), SqlCommand)
cmd.Prepare()
Else
cmd = New SqlCommand
For Each p As SqlParameter In parameters
cmd.Parameters.Add(p)
Next
commandCache.Add(sql, cmd)
End If

If tran Is Nothing Then
cmd = New SqlCommand(sql, con)
Else
cmd = New SqlCommand(sql, con, tran)
End If

Return cmd
End Function
End Class

David
 
David Browne said:
And _how_ to do it is simple. Use a public variable in a module, just
like VB6. Or make it a "Shared" (static in C#) member of some class.
Another fun way to share a Connection, and one which works perfectly well in
ASP.NET as well as winforms apps, is to keep the connection in thread-local
storage. ASP.NET pools worker threads, so you won't get too many
connections open. Each worker thread will have its own connection. The
nice thing about this is that if you have a lot of layers of business logic
and MethodA calls MethodB calls MethodC, and they all need the database,
they will all share the same connection. This can actually reduce the
number of open connections.

class ThreadLocalConnection
{
[ThreadStatic]
static SqlConnection con;
[ThreadStatic]
static string lastConn;

public SqlConnection Connect(string ConnectionString)
{
if (con == null || ConnectionString != lastConn)
{
if (con != null)
{
con.Dispose();
}
con = new SqlConnection(ConnectionString);
con.Open();
lastConn = ConnectionString;
}
return con;
}
}

David
 
Yeah you could do all that .. but I still feel like sharing a connection
object is not as good a solution as letting ADO.NET connection pool for you.
(Just my views before we start a war).

Here are my reasons --

a) You end up writing an application that cannot leverage connection pools -
thus locking yourself in an architecture where you will always be restricted
to a limited user scenario - this being much lesser than hundereds of users
atleast in the case of Sql Server.
b) The performance difference between connection pooled and connection
object shared is not that much. And you are writing extra code for that and
maintaining extra code and debugging extra code and checking in/out extra
code and .... .. ..
c) You are reinventing the wheel - if microsoft ever changes their paradigm,
you will be left in high water - just like I worked with this company where
they insisted on other threads twiddling with the form's UI - the argument I
heard back then was - this is non-blocking, the user is much slower than the
pc .. blah blah and they went ahead and put that in their base classes - and
now with .NET 2.0, they will get a nasty exception - so essentially they
will now not be able to upgrade to 2.0. Not to mention, in the very same
application they remote datasets a lot - so they miss out on the performance
gains via dataset.remotingformat.
d) MARS - what if you are sharing one object and using MARS - you will hit
the 10 command limit sooner than you can say whatchamacallit. Not to
mention - there is nothing you can now do to monitor this limit because god
knows who all is sharing your single object.
e) Blocking nature - pooling ensures that as your app needs grow, new
physical connections are created - one object means you are stuck
implementing all that.

I have tonnes of more reasons - and even for the simplest of applications -
say a desktop app touching an access db, I still recommend connection
pooling versus implementing your own hoopla.

Not to mention - if you indeed wanted to restrict the user to one single
physical connection as indeed your model would - you can specify that via
the connection string with ZERO code written. I think it makes sense to
leverage of all the code Microsoft has written and tested and debugged - and
that is running in thousands of applications worldwide. Why invent your own
wheel?? It might not be perfectly square .. uh huh I mean round !!

Just my views :)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik




David Browne said:
David Browne said:
And _how_ to do it is simple. Use a public variable in a module, just
like VB6. Or make it a "Shared" (static in C#) member of some class.
Another fun way to share a Connection, and one which works perfectly well
in ASP.NET as well as winforms apps, is to keep the connection in
thread-local storage. ASP.NET pools worker threads, so you won't get too
many connections open. Each worker thread will have its own connection.
The nice thing about this is that if you have a lot of layers of business
logic and MethodA calls MethodB calls MethodC, and they all need the
database, they will all share the same connection. This can actually
reduce the number of open connections.

class ThreadLocalConnection
{
[ThreadStatic]
static SqlConnection con;
[ThreadStatic]
static string lastConn;

public SqlConnection Connect(string ConnectionString)
{
if (con == null || ConnectionString != lastConn)
{
if (con != null)
{
con.Dispose();
}
con = new SqlConnection(ConnectionString);
con.Open();
lastConn = ConnectionString;
}
return con;
}
}

David
 
These are all good reasons especially for ASP. I don't think any strategy
that tries to manage connections for ASP makes any sense at all. However,
for client/server systems, I think connection pooling can be needless
overhead and MARS is often overkill.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________

Sahil Malik said:
Yeah you could do all that .. but I still feel like sharing a connection
object is not as good a solution as letting ADO.NET connection pool for
you. (Just my views before we start a war).

Here are my reasons --

a) You end up writing an application that cannot leverage connection
pools - thus locking yourself in an architecture where you will always be
restricted to a limited user scenario - this being much lesser than
hundereds of users atleast in the case of Sql Server.
b) The performance difference between connection pooled and connection
object shared is not that much. And you are writing extra code for that
and maintaining extra code and debugging extra code and checking in/out
extra code and .... .. ..
c) You are reinventing the wheel - if microsoft ever changes their
paradigm, you will be left in high water - just like I worked with this
company where they insisted on other threads twiddling with the form's
UI - the argument I heard back then was - this is non-blocking, the user
is much slower than the pc .. blah blah and they went ahead and put that
in their base classes - and now with .NET 2.0, they will get a nasty
exception - so essentially they will now not be able to upgrade to 2.0.
Not to mention, in the very same application they remote datasets a lot -
so they miss out on the performance gains via dataset.remotingformat.
d) MARS - what if you are sharing one object and using MARS - you will hit
the 10 command limit sooner than you can say whatchamacallit. Not to
mention - there is nothing you can now do to monitor this limit because
god knows who all is sharing your single object.
e) Blocking nature - pooling ensures that as your app needs grow, new
physical connections are created - one object means you are stuck
implementing all that.

I have tonnes of more reasons - and even for the simplest of
applications - say a desktop app touching an access db, I still recommend
connection pooling versus implementing your own hoopla.

Not to mention - if you indeed wanted to restrict the user to one single
physical connection as indeed your model would - you can specify that via
the connection string with ZERO code written. I think it makes sense to
leverage of all the code Microsoft has written and tested and debugged -
and that is running in thousands of applications worldwide. Why invent
your own wheel?? It might not be perfectly square .. uh huh I mean round
!!

Just my views :)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik




David Browne said:
David Browne said:
Sure, there is nothing to stop you from creating and opening a
persistent connection in a Windows Forms using ADO.NET. No, this won't
work with ASP.NET applications.
It does save time because even the connection pool Open takes time to
execute. It also prevents you from leveraging server-side functionality
that you CAN use in ADO.NET. The problem is, it limits the number of
users your server can handle--from several hundred to several thousand
or so.
Another fun way to share a Connection, and one which works perfectly well
in ASP.NET as well as winforms apps, is to keep the connection in
thread-local storage. ASP.NET pools worker threads, so you won't get too
many connections open. Each worker thread will have its own connection.
The nice thing about this is that if you have a lot of layers of business
logic and MethodA calls MethodB calls MethodC, and they all need the
database, they will all share the same connection. This can actually
reduce the number of open connections.

class ThreadLocalConnection
{
[ThreadStatic]
static SqlConnection con;
[ThreadStatic]
static string lastConn;

public SqlConnection Connect(string ConnectionString)
{
if (con == null || ConnectionString != lastConn)
{
if (con != null)
{
con.Dispose();
}
con = new SqlConnection(ConnectionString);
con.Open();
lastConn = ConnectionString;
}
return con;
}
}

David
 
Sahil Malik said:
Yeah you could do all that .. but I still feel like sharing a connection
object is not as good a solution as letting ADO.NET connection pool for
you. (Just my views before we start a war).

Here are my reasons --

The main attraction for using a persistent database connection is that it
removes the possibility for connection leaks.


But I really don't disagree. I was just saying it is possible to have
global database connections both in ASP.NET and winforms. Personally, I use
the connection pool.

David
 
Conn Pooling --
As far as conn pooling goes -- Here is a good reading on this topic -
http://weblogs.asp.net/angelsb/archive/2004/10/08/240123.aspx
As you can see this discussion based on performance only is extremely
subjective, but given that I have lesser code to
maintain/write/test/debug/release/update, pooling seems a better logical
choice. (Again - super subjective personal opinion :-) ).
While there isn't much perf difference though, you might have more than
required open connections - but those can be easily tweaked by specifying
connection string parameters. Why invent your own wheel?

MARS -
As far as MARS goes, MARS is more to solve a particular problem so rather
than viewing it as an overkill in a client/server situation, it's either
solving a situation that nothing else could solve, or it is being misused.
(Sidenote: I am glad that by default all this newfangled stuff in Sql Server
2k5 is turned off by default forcing admins to read up on it before they
turn it on. )

There are two scenarios that MARS solves very very well that nothing else
could do so far -

a) Two commands - select and update on the same isloation
level/transaction - you could not do that before MARS.
b) Cleaner code if indeed you wish to read and update at the same time.

MARS like anything else has it's don't do's especially when you introduce
transactional semantics around the whole issue.
So is using MARS in a winforms client/server app an overkill? .... ... well
it solves two situations nothing else can solve, so nothing can replace MARS
in those two situations - but in all other situations what you have is a
"Misuse of MARS" // not overkill.

I will be putting up a post on my blog regards MARS best practices sometime
before monday night and would absolutely love to hear your additions to it.
:)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik





William (Bill) Vaughn said:
These are all good reasons especially for ASP. I don't think any strategy
that tries to manage connections for ASP makes any sense at all. However,
for client/server systems, I think connection pooling can be needless
overhead and MARS is often overkill.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no
rights.
__________________________________

Sahil Malik said:
Yeah you could do all that .. but I still feel like sharing a connection
object is not as good a solution as letting ADO.NET connection pool for
you. (Just my views before we start a war).

Here are my reasons --

a) You end up writing an application that cannot leverage connection
pools - thus locking yourself in an architecture where you will always be
restricted to a limited user scenario - this being much lesser than
hundereds of users atleast in the case of Sql Server.
b) The performance difference between connection pooled and connection
object shared is not that much. And you are writing extra code for that
and maintaining extra code and debugging extra code and checking in/out
extra code and .... .. ..
c) You are reinventing the wheel - if microsoft ever changes their
paradigm, you will be left in high water - just like I worked with this
company where they insisted on other threads twiddling with the form's
UI - the argument I heard back then was - this is non-blocking, the user
is much slower than the pc .. blah blah and they went ahead and put that
in their base classes - and now with .NET 2.0, they will get a nasty
exception - so essentially they will now not be able to upgrade to 2.0.
Not to mention, in the very same application they remote datasets a lot -
so they miss out on the performance gains via dataset.remotingformat.
d) MARS - what if you are sharing one object and using MARS - you will
hit the 10 command limit sooner than you can say whatchamacallit. Not to
mention - there is nothing you can now do to monitor this limit because
god knows who all is sharing your single object.
e) Blocking nature - pooling ensures that as your app needs grow, new
physical connections are created - one object means you are stuck
implementing all that.

I have tonnes of more reasons - and even for the simplest of
applications - say a desktop app touching an access db, I still recommend
connection pooling versus implementing your own hoopla.

Not to mention - if you indeed wanted to restrict the user to one single
physical connection as indeed your model would - you can specify that via
the connection string with ZERO code written. I think it makes sense to
leverage of all the code Microsoft has written and tested and debugged -
and that is running in thousands of applications worldwide. Why invent
your own wheel?? It might not be perfectly square .. uh huh I mean round
!!

Just my views :)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik




David Browne said:
message
Sure, there is nothing to stop you from creating and opening a
persistent connection in a Windows Forms using ADO.NET. No, this won't
work with ASP.NET applications.
It does save time because even the connection pool Open takes time to
execute. It also prevents you from leveraging server-side
functionality that you CAN use in ADO.NET. The problem is, it limits
the number of users your server can handle--from several hundred to
several thousand or so.

--

And _how_ to do it is simple. Use a public variable in a module, just
like VB6. Or make it a "Shared" (static in C#) member of some class.

Another fun way to share a Connection, and one which works perfectly
well in ASP.NET as well as winforms apps, is to keep the connection in
thread-local storage. ASP.NET pools worker threads, so you won't get
too many connections open. Each worker thread will have its own
connection. The nice thing about this is that if you have a lot of
layers of business logic and MethodA calls MethodB calls MethodC, and
they all need the database, they will all share the same connection.
This can actually reduce the number of open connections.

class ThreadLocalConnection
{
[ThreadStatic]
static SqlConnection con;
[ThreadStatic]
static string lastConn;

public SqlConnection Connect(string ConnectionString)
{
if (con == null || ConnectionString != lastConn)
{
if (con != null)
{
con.Dispose();
}
con = new SqlConnection(ConnectionString);
con.Open();
lastConn = ConnectionString;
}
return con;
}
}

David
 
The main attraction for using a persistent database connection is that it
removes the possibility for connection leaks.

---> Yes !! Especially if you don't have time to write a datalayer. Or in
certain situations like when you need to gather Transactions from various
commands, and run them sequentially, your datalayer HAS to expose an open
connection - and then you are at the mercy of the programmer writing the
code, and he has a finite nonzero screw up probability. I think this
situation can be handled by having a thread run in your datalayer that keeps
a tab of all open Sql connections handed out and closes them out after
certain configurable # of seconds - I have yet to see someone write a
perfect datalayer, but I am sure it's do-able.
But I really don't disagree. I was just saying it is possible to have
global database connections both in ASP.NET and winforms. Personally, I
use the connection pool.

I use conn pool too :-). Thanks for your answer.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
 
William (Bill) Vaughn said:
These are all good reasons especially for ASP. I don't think any strategy
that tries to manage connections for ASP makes any sense at all. However,
for client/server systems, I think connection pooling can be needless
overhead and MARS is often overkill.

Not exactly. Connection pooling is very handy, specially, if you are doing
multithreaded application (as IMO every serious application should be done
multithreaded - the reason is simple: you don't want UI to freeze while data
is loading or saving or some other lengthy operation is preformed).
And doing multithreading without connection pooling is a bad choice.
And the pool overhead is really minimal.
 
To add onto Miha's point, If you had a multithread app using one single
connection object instance. If the multiple threads started to issue
commands simultaneously (how would you control this without blocking? And
soon as you do control using blocking your performance goes down the tubes),
you would hit the 10 session pools limit and not even know about it.

The same argument applies to ASP.NET apps.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
 
Back
Top