I wonder whether there is a way to determine the Connection ID and LocalEndpoint's port used by MySql Connection on the C# side.
I know that I can run:
select * from information_schema.processlist
where id = connection_id();
However, my question is whether I can get these details (or at least the connection ID) without executing this SQL statement, that is, right from the Connection object itself (as this information DOES exist within the connection's underlying type and TCP socket)
Thanks :)
The documentation for the connection_id() function says that it returns the thread ID of the current connection. If you check the documentation for MySqlConnection you may find that the MySqlConnection equivalent of ClientConnectionId is ServerThread - I have done some testing & found that it contains the same value as returned by the query - but that may not be guaranteed.
I have not found a way of determining the TCP port from publicly accessible properties/methods.
The connection string is parsed into Properties of the Connection class. It might have ceased existing once it was processed. Look at the Propeties you have availible: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx#Properties
As for getting Connection details - that is problematic. Internally the SQLConnection class is doing Connection Pooling. So the same low-level connection might be re-used for a request that comes soon after. Like Thread ID's, it is the kind of thing you should not really access in your code.
These values could change even during execution without any obvious forwarning, rhyme or reason (there is still a reason, but it is hard to even get a decent guess). The Behavior Might change between Framework Versions, Specific Circumstances in that Millisecond, or even if your Grandmother visits or wheter you have a full moon or not today.
Related
I'm changing our DAL to an async DAL.
Looking at :
await _conn.OpenAsync().ConfigureAwait(false);
I see that there's an async method for open connection.But why there's no async method for closing connection ?
A shared connection might used by others
Might return to the connection pool
It is an I/O operation
Possible delayed / time-consuming operation
(I might be wrong about all four above :-))
Question
It seems logic ( to me) that there's should be an async close method for a connection.
Is there a reason why there's not ?
PS I will obviously will use DAPPER at the end , but just for practicing , I've decided to create small mini mini dapper alike DAL.
A shared connection might used by others
Why would this make calling close on it take a long time? If anything this would mean that, in cases where the connection is still being used by others all that "closing" it means is indicating that you no longer needed it, and the actual underlying connection doesn't need to be closed.
It is an I/O operation
Not necessarily. As you said, if it's pooled/shared, then it's just returned to the pool, no IO would happen at all.
And what makes you think that, even if the underlying connection is being closed, that it would take a long time. All that needs to happen is to stop paying attention to the connection, possibly sending a courtesy message through the connection saying that you're done. That's not going to take a long time. You don't need to wait for any type of response to such a message, so you aren't waiting for a completed network round trip in this method.
Possible delayed / time-consuming operation
Why would it be time consuming? If it is delayed (if, for example, the connection is pooled and you're closing it when you're the last user of it) it means that that it'll likely be closed after a bit, but you aren't needing to wait for that.
Marking an object as "no longer in use" simply isn't time consuming, and at the end of the day that's all you're really doing.
In fact, IDbConnection interface (the one required to implement to develop an ADO.NET connection provider along with other interfaces like IDbCommand) doesn't provide OpenAsync.
Thus, OpenAsync is an implementation detail of DBConnection and, for example, it's the base class of System.Data.SqlClient.SqlConnection.
Why there's no CloseAsync? This should be asked to a .NET Framework Development Team member. When there's a design decision like this, usually it's motivated because of some particular requirement either in the framework itself or in some .NET-based solution developed by Microsoft or some partner. Maybe there's a potential question here: Why IDbConnection doesn't define both Open and Close asynchronous flavors? What about an IDbConnectionAsync interface in order to avoid a breaking change with exisiting code?.
BTW, I suspect opening a connection consumes more time than closing it, because closing process can be queued since the caller just expects an OK I'll do it (from the database server) while opening a connection it's not just signaling but an immediate availability of the connection itself.
Since network connectivity might slowdown the connection opening process, it seems like this is the main reason to implement it as an async operation.
I've a C# client application that need to checks a table on a Postgres db every 15 minutes. The problem is that I need to install this client into more or less 200 client so, for that I need to close the DB connection after the query.
I use .Close() method but, if I check on pg_stat_activity table on Postgres DB, I can see the connection still open in IDLE status. How can I fix that issue? Is it possible to close definitely the connection?
thanks,
Andrea
Like most ADO.NET providers, Npgsql uses connection pooling by default. When you Close() the NpgsqlConnection object, an internal object representing the actual underlying connection that Npgsql uses goes into a pool to be re-used, saving the overhead of creating another unnecessarily. (See What does "opening a connection" actually mean? for more).
This suits most applications well, as it's common to want to use a connection several times in the space of a second.
It doesn't suit you at all, but if you include the option Pooling=false in your connection string, it will override this default, and Close() will indeed close the actual connection.
I realize that there is no way to atomically guarantee:
if(hasInternet)
doDatabaseCall();
However, what is the correct way of handling connection problems when dealing with DbConnection and DbCommand objects in the .NET world? I'm specifically interested in the MySqlConnection and MySqlCommand objects but assume (hope) its pattern of exceptions is the same as SQL Server's classes.
I'd assume that if the internet goes down before calling, conn.Open(), a MySqlException gets raised. I'd also assume the same happens if you call ExecuteReader or ExecuteNonQuery and the internet has gone down.
I'm not sure because the docs for the MySql objects don't say. The SqlServer objects just say that it might raise a SqlException which means:
An exception occurred while executing the command against a locked row. This exception is not generated when you are using Microsoft .NET Framework version 1.0.
That doesn't seem to cover connection issues... What I'd like to do is handle the exception, wait for some amount of time, and start over again. My application's sole purpose is to execute these database calls and its running on a dedicated system so retrying forever is really the best option I believe. That said, I would love to differentiate between connection exceptions and other kinds of database exceptions, is that possible?
I've done some testing and it appears to work as I assume but does it work in all edge cases? Such as: the command was successfully sent to the database server but the connection goes down before or while the results are being returned? If it doesn't work in all edge cases then I'm going to have to: execute a command, query for the desired state change, execute the next command, etc. It's important that each command goes through.
I am connecting to a port on localhost that is forwarded via SSH to a remote server if that makes a difference.
As for the SqlDataProvider:
The SqlException exception has a several properties that give you detailed information why your operation failed.
For your use case the "Class" property might be a good choice. It's a byte indicating the severity of the exception.
See: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlexception.class.aspx
If that is not specific enough, you can examine that individual errors in the Errors collection.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlexception.errors.aspx
Based on that information you can decide whether to retry.
I have an SQL server on a server at home (which is an Atom processor with 1GB ram), and i'm using it to store data for one or two of my applications. I was wondering if i should create a DataContext object when the program starts then hold onto it for the entire life of the app, or only create the connection when necessary. What happens if the application dies suddenly? does the connection get cleaned up?
Unless you're handing DataContext object an already open SqlConnection, DataContext will automatically close the database connection after the completion of a database operation anyway. So it won't keep the connection open. You can see this by looking at DataContext class in Reflector or you can read ASP.NET MVC Tip #34: Dispose of your DataContext(or Don't) blog post. So even if your DataContext object continues to live, there should not be any open database connection.
If you're handling the database connection outside of DataContext and keeping it open, then you really should not do this. Generally, you should create and use resources when and where you need them including DataContext object. There is no need to keep a database connection open without any demand for it, close it so that it gets released back into the pool to serve another database connection request. As I said, if you're letting DataContext handle the database connection, you don't need to do anything special as far as the database connection is concerned.
If your application crashes suddenly and terminates, you should be ok since everyhing will die including open database connections and the underlying connection pool associated with your application domain.
Bring up the data context when you need it and get rid of it when you're done.
Having one global datacontext means you have to pass it around to everything that needs it. (Every method you write that needs database access has an extra parameter in its signature).
Having a single global datacontext is also just going to become a pain if you ever decide to multi-thread one of your apps.
Have you looked at SQL connection pooling in .NET? Have a look at the article at http://msdn.microsoft.com/en-us/library/8xx3tyca%28VS.80%29.aspx. Connection pooling takes care of all the dirty work for you and automatically cleans up after itself if an error occurs in your program. It's pretty efficient at re-using connections so there is very little overhead in re-using the connections (creating the first connection when your program starts still has the same cost). It might be overkill for small applications but it's probably a good habit to get into for larger projects.
From MSDN:
While the SqlDataReader is being used, the associated SqlConnection is busy serving the SqlDataReader, and no other operations can be performed on the SqlConnection other than closing it. This is the case until the Close method of the SqlDataReader is called. For example, you cannot retrieve output parameters until after you call Close.
a) Why couldn’t you use SqlConnection for anything else? After all, when ExecuteQuery() returns SqlDataReader object, the data from DB has already been retrieved and populated SqlDatareader object. Thus I don’t see how or why SqlConnection should still be serving SqlDataReader object?!
b) More importantly, for what reason would it be bad idea to retrieve output parameters before you call Close() on SqlDataReader?
c) When above quote mentions that no other operations can be performed on SqlConnection, what operations does it have in mind? Just those that would require to connect to remote sql server, or we can’t use any members of SqlConnection instance?
a) When ExecuteReader returns, the data has not all been retrieved and populated in the reader, it may still be streaming back from the database. That's the whole point of the SqlDataReader because it's more efficient to do this than to load it all up front.
b) You can't retrieve output parameters until after the reader has finished because of the way the Tabular Data Stream (TDS) protocol is structured. The output parameters are not physically sent down the stream until after the result set data.
c) It means none of the operations except Close are documented as being guaranteed to work. Whether they actually do work or not is irrelevant because that is an implementation detail rather than a contract, and programming against implementation details is a recipe for disaster.
Why do you want to re-use the connection anyway? The connections that SqlConnection uses are pooled behind the scenes, so when you dispose one it doesn't really get rid of all the resources, it just returns the connection to the pool. This means you can use the connection for the shortest time possible, ideally within a using block, and not have to worry about this type of thing. Just create a new connection whenever you need one, and don't bother trying to re-use them as it's already happening behind the scenes.
Uhm... you can in SQL Server 2005. Please read this page:
http://msdn.microsoft.com/en-us/library/ms345109.aspx
SqlDataReader doesn't return the entire table in one fetch, much like a StreamReader wouldn't return the entire file. Obviously in reality it will for small tables, but only one connection is being served. That's using blocking for network access though - just open a second connection if you need to do something else asynchronously.
The code you have posted is actually designed to be run with the jQuery library. You can find out more information about jQuery at http://jquery.com/. Mootools, while also a javascript library, is a different thing and the code you posted would not work (you can learn more about mootools at http://mootools.net/).
What exactly are you attempting to achieve by including this code on your page / site?