views:

822

answers:

11

Hi I am writing a data access layer. I am confused about managing connections in the system. I know that .net uses connection pooling. But I do not want to open and close database connections in all dml operations or in all sql query's. How can I handle this? Where and when ( maybe in global asax which uses data access layer or in the data access layer ) the connections should be managed?

A: 

I want to open connection once. But I am confused about how can I do this? ( Data access layer can be used in windows forms but generally it will be used in asp .net web applications. )

please edit your original post, and do not use this like a regular message board.
StingyJack
@Unknown- welcome to StackOverflow. This site works a little differently then most message boards. Instead of posting *answers* with clarifying info, you should edit your question or post comments.
Michael Haren
Yeah... what he said. I have written it too many times and am getting sloppy.
StingyJack
thank you; sorry :(
In any event, opening a connection only once in ASP.NET web apps is an extremely bad idea -- it will lead to scalability issues at best, and unclosed connections and resource leaks in a typical implementation. Go with @StingyJack's answer. He's right.
John Rudy
It won't result in unclosed connections nor will it result in resource leaks (the GC will eventually call the finalizer, which will close and dispose of the connections). It WILL cause scalability problems, however.
Robert C. Barth
+6  A: 

Why don't you want to open/close the connection for every discrete logical operation? Most existing DALs behave that way. Usually it's not a good idea to try to outsmart what the runtime will do for you automatically, such as intelligently manage your connections. You should have a strong, demonstrable technical need before putting in the time and effort to add that complexity to your app.

Rex M
+9  A: 

You should open and close sql connections for each query, unless you are running a batch of statements.

"Open late, close early" is how you should always handle database connections.

If you are going about it in the traditional manner (making your own queries), MS has already written a nice data access interface. The enterprise library (application blocks) for data have all of the nice well formed bells and whistles.

If you dont want to bother with writing queries, I suggest you look at linq2Sql or linq2EF (preferred). They will greatly simplify your coding.

StingyJack
+1 - I agree. If you are going to write your own DAL at least pop open the Enterprise Library code. It will help guide you.
tyndall
A: 

Connection management should not be managed by the DAL.

The one and only layer that can be responsible / can decide whether a new connection should be opened, or a connection should be closed, is the service layer or application layer which uses the DAL. That layer is the only layer that is aware of the context, and so this layer is where you can decide whether you should close a connection, or leave it open since there aer other DB communications that should use the same connection.

Frederik Gheysels
Is the data access layer not the one between the database and all other code?
StingyJack
The DAL is the layer that makes abstraction of your database, and the way you access it. It is being used by other code by calling methods on the DAL, you execute queries. However, the DAL itself can imho not decide whether a new connection need to be openend, or in which transaction the query
Frederik Gheysels
... must be executed . (300 char's is not much)
Frederik Gheysels
no, 300 chars is not enough sometimes. =). I can see your point in some scenarios, however in mine it doesnt work that way. We use the DAL to get a dataset/table, and then hydrate groups of objects in the biz tier. In this way its more of a semi-batched object creation, so similar.
StingyJack
IMHO, the DAL should return a usable object to the Application Layer after completing all tasks related to the database (including closing connections). If the Application Layer **knows** about connections, then this blurs the fine line between the layers.
Cerebrus
A: 

You should indeed open/close for every operation. Do not look at Connection use as a high-cost operation because it simply isn't. As you open connections on your site, they will be created in a connection pool. When you "close" the connection, the connection pool does not release the connection: it keeps it on-hand, ready for reuse. Thus, while the very first call resulting in a new connection takes a bit longer, the subsequent connections are very fast.

Update: this is particularly true in a web application! Do not attempt to open a connection just once in your global object and re-use it across all threads or your site simply won't work.

Mark Brittingham
what about transaction management, which is closely related to connection management (as a regular transaction cannot span multiple connections)
Frederik Gheysels
Simply put - you cannot perform a transaction over multiple web pages by maintaining an open connection. If you have collected data over multiple pages, you'll store the information in the session or, in some other way, "save it up" until it is time to commit all changes together.
Mark Brittingham
A: 

My advice after writing several datalayers in .Net (and a good few more in VB6 previously) is:

  1. use datasets not readers if at all possible.
  2. make and break the connections (you can't have >1 reader open on any one connection anyway).
  3. do the work with paramaterised sps on the back end. 3.5 make sure all tables have a unique one-field primary key!

slightly OT?...

  1. use code generation (yours or bought in) to produce ORM classes - but be aware that they are not the be-all and end all (the one table at a time stuff is handy - but can make you write ugly inefficent code where one query on the back end with joins or a cunning SP or view will do the job MUCH more nicely).
  2. read up on the Transaction method of the Connection object - very very handy (though some purely db things that needs a transaction (e.g. a delete where there are relationships) should be on thcan be a transaction on the back end.

My own latest basic DAL (no ORM) took me half an hour to write and is compact and pretty efficient. The MS enterprisey stuff is HUGE!!!

One last thing - I personally think that strongly-typed datasets generated from xsds have a high annoyance (and bloat) to gain ratio - and the way they make you handle NULL sux big time. All the code you write to use them is bloaty too... or you end up downcasting them to DataSet to actually get a library of efficient, non-repetitive code.

kpollock
I would disagree about #1 preferring datasets over datareaders. DataSets come with a lot of overhead. DataReaders take up fewer resources and, let's face it, most of our development requires getting a list of data and displaying it. For those purposes DataReaders are much better. IMHO.
I strongly agree that the Enterprise App blocks are mostly overkill. I prefer to write my own DAL's in almost every case.
Cerebrus
I initially used DataReaders, but found the code cleaner with DataSets. I also had some issue with DataReaders and an existing in-house (simple table) ORM due to not being able to have >1 reader open per connection. Which we would have needed to wrap it in a transaction.
kpollock
With the advantage of simple use and excellent documentation/samples coverage, DataSets are heavily untyped and retain rather strong object-relational "impedance". They are often ideal match for small short-term projects, but fail to OOD solutions (in maintenance, extensibility) when project grows.
DK
I should add that I rarely use DataSets with multiple tables, since I use them purely for display. Inserts/Updates/Deletes call parameterised SPs. How it scales depends on how the ORM is done/used works - I use SQL for all the heavy lifting.... [cont]
kpollock
...I'll admit that my business logic layers are often either very lightweight, part of the SQL back end or handled by workflow engines (homegrown or Tibco).
kpollock
... and I write a lot of generic code (e.g. to work with 3rd party grids etc) so that strongly typed datasets are just a pain that meed tobe bypassed by downcasting (or lead to deep, rigid control hierarchies - not the greates of plans with VS given the issues with visual inheritance).
kpollock
A: 

ok I will open and close connection in every dml or select query run. kpollock can you send me your code? my aim is not copy all of them :) I have started to write something. and why microsoft do not use command pooling? mail : [email protected]

Dude, you obviously are not reading what we are telling you. Please read the full suggestions, and do try to look at the Enterprise library. They are free and follow the best practices for database connections. Command pooling? What on earth is that?
StingyJack
keep going with your own code - but do let me know if/when you get stuck. You'll learn more that way :-).
kpollock
A: 

This will be updated.

A: 

I wrote my code. Can you write about my code? Errors or which features can I add it?

This is the last thing which is written in this topic but it is not seen at the bottom:(

+1  A: 

What about operations that has to occur as a transaction?

It is your BL that does the operation and logic/ validation right?

Let's say you have a BL layer that

  1. updates your customer account information. (DAL -> update customer record)
  2. insert an adress record. (DAL -> insert adres)
  3. validates your customer against an third object. (DAL -> get client & adres & validation object)

the outcome: customer not valid. So you have to roll back your transaction.

How would one go about solving this issue?

That's what I'm saying. :)The dal shouldn't be responsible for connection and transaction management, but the service layer should be responsible.
Frederik Gheysels
A: 

I'm not clear on the etiquette for answering old questions, and I couldn't figure out how to comment on another answer (I'm brand new to SO, and I'm not quite through my first cup of coffee today, so cut me some slack =]).

I always write my DALs to open/close connections with every query and let the driver's connection pooling do the work of connection management.

However, I have a multi-user desktop app that uses a shared MS Access DB (SQL Express wasn't around in a really usable form when this app was made), and I've occasionally seen errors indicative of corruption. This MS article recommends using only a single connection for the entire app:

"Repeatedly opening and closing a Microsoft Access database is not recommended. Open the database once at the beginning of the application, and then close the database at the end of the application."

My app is multi-threaded, so I'm assuming I'd have to revise the recommendation to "open one connection PER THREAD" to avoid collisions. Does anyone have any experience using shared Access databases with OLEDB and similar corruption issues?

Jared