I have a c# server that is connecting to a mysql server for data. This c# server is a backend server for a game, that has an open thread for every player currently logged in. How do I go about doing the mysql connection, an open connection for each thread? A single connection using locking for all threads?
I read somewhere that there is a 'threadpool' for this. Is that true? If so, is this the proper way to use it:
using(var conn = new MySqlConnection(DatabaseHelper.getConnectionString()))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT username FROM characters WHERE id=1";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
user = reader.GetString("username");
}
}
}
I think you are confusing two different resources here; you may indeed want an open thread (effectively a process) for each player logged on, but this doesn't mean you should have a connection to the database open for each player constantly, as things like database connections, file handles etc are not managed resources and should be freed up as soon as you are finished with them.
There's a good introduction and explanation of C# threading here.
You should only open a connection to the database when you need it. This means your data access classes could be instantiated many times (this is the simplest design) each with their own connection. If you use connection pooling, which I feel you actually might have been asking about, then you'll benefit further. Moving towards a static database connection design (where many people share the same dao classes) can be much more problematic as you may have to synchronize certain resources, ensure certain variables can only be accessed in sequence via locking or similar, and more.
You can read more about this here for example. Microsoft also talk about the benefits of connection pooling here.
The code you have above is a good starting point for connecting to the database, by including the using statement you are closing and disposing of the connection as soon as you are finished with it; you might also consider the following improvements:
using(var conn = new MySqlConnection(DatabaseHelper.getConnectionString()))
{
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandType = CommandType.Text;
//Parameterize your queries!
cmd.CommandText = "SELECT username FROM characters WHERE id=?"; //Use ? as placeholder for parameters, and add parameters in the order they appear in your query.
cmd.Parameters.Add(new MySqlParameter("#userid", MySqlDbType.Int, userid));
using(IDataReader reader = cmd.ExecuteReader())
{
//You should only expect one record. You might want to test for more than 1 record.
if (reader.Read())
{
user = reader.GetString(reader.GetOrdinal("username")); //Think also about null value checking.
}
}
}
}
You might have a DAO class, or a method on a user class to do this. For example, if it was a method on user, you might do something like:
User myUser = new User(7);
myUser.Load();
Inside of Load, one of the methods you might call is PopulateFromDB() which would contain the code above, and would load all of the properties of this user. You might also have a DAO class that does the same thing:
UserLoader loader = new UserLoader();
string userName = loader.GetUserName(int userId);
which would return the username using the code in the example above. I'd prefer this method to be on a class like User as it's logically connected to it. However, you then run the risk of mixing the DAO logic with the user business logic, which is a topic all on it's own.
Rather than write a lot of this data access logic, you might consider looking at some form of framework like an ORM or similar - this question has already been answered for MySql on SO. This could also save you a lot of time and effort, and will allow you to concentrate on design.
Related
What is wrong with this code ? how to detect the session state, code given below does not work as expected?
OleDbCommand cmd4 = new OleDbCommand(sql4, conn4);
if (conn4.State == ConnectionState.Open) {
conn4.Close();
}
conn4.Open();
Connections implement IDisposeable. For Disposeables I have one rule:
"Never split up the creation and disposing of anything Disposeable. Create. Use. Dispose. All in the same piece of code, ideally using the using block."
There are some really rare exceptions like Logfiles, but a Database is not suiteable for any of those uses anyway (it has too many things that can go wrong on top of the issues files experience).
My question might be silly or may not be a question at all, but here it goes..
I am performing quite some database operations in my ASP.net MVC project where I am creating two objects each and every time namely, SqlConnection and SqlCommand.
I have shown an example below
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand("sRegisterUser", connection))
{
I am doing all these different operations inside one class under different methods.
My question is how can I reduce the creation of these objects each and every time? How can I create them globally
PS: sRegisterUser is a stored procedure, like wise other methods use different procedures which gets different values as parameters.
Please help me out.
Thanks for any help in advance.
The answer is, don't. You do not want to share these objects, you are using them appropriately.
You don't. You either keep the object alive, which is bad. Or you dispose it the way you should, and currently do.
So, why do you have use using?
Since using is necessary for disposing the handles in Windows.
You could also write this, which is similar to using using:
SqlConnection connection = new SqlConnection(connectionString);
connection.Close();
connection.Dispose();
using also disposes when the code above throws an error. Using using is actually the shortest way to code this.
So the error-save version should be:
SqlConnection connection;
try
{
connection = new SqlConnection(connectionString);
...
connection.Close();
}
finally
{
connection.Dispose();
}
As others already said, there is nothing wrong with what you're doing right now. ADO.NET objects are meant to be used and disposed of. As a rule of thumb you should create them as late as possible and dispose of them as soon as possible.
With that being said, I understand what you're trying to do here and I do have a few ideas you might be interested in for making your life easier while keeping good programming practices.
If you want to make the code more concise you can chain using statements:
using (var cn = new SqlConnection(yourConnectionString))
using (var cmd = new SqlCommand(yourQuery, cn))
{
// do stuff
}
The IDE will not try to indent the second block, making it easier on you to read.
You can also create an abstraction layer for your procedure:
public static class Procedures
{
public static void RegisterUser() // add whatever parameters you need
{
using (var cn = new SqlConnection(yourConnectionString))
using (var cmd = new SqlCommand(yourQuery, cn))
{
// do stuff
}
}
}
From then on you can execute your procedure simply by calling:
Procedures.RegisterUser();
Another alternative is to introduce a factory pattern to get your objects. This alone won't reduce their number but it might help in getting them all set up already (ie correct connection string).
You also can be creative and combine the two patterns. A custom class implementing IDisposable can take care of creating the necessary ADO objects, open the connection, execute your query, close the connection and dispose of any objects that needs disposal when it is itself disposed of.
Take your pick.
So hopefully with some CSLA skills out there can help me see a better way with this one. I have a situation where I want to manually create my transaction from outside the object and set my transactionAttribute to manual.
So I have some code that looks like this:
using (SqlConnection conn ConnectionManager<SqlConnection>.GetManager("Db").Connection)
{
connectionTransaction = conn.BeginTransaction();
objectRef = objectRef.Save();
//other logic here
objectRef = objectRef.Save();
connectionTransaction.Commit();
}
Then inside the save method there is something like this for the data access:
using (var conn = ConnectionManager<SqlConnection>.GetManager("Db").Connection)
{
using (var cm = conn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "Proc_Name";
// param definitions
cm.ExecuteNonQuery();
}
}
When I do this I receive the following error:
ExecuteNonQuery requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.
Ok so that makes sense what it is saying and I could easily fix by assigning the transaction to the command. But I'm wondering if this is actually structured correctly according to CSLA best practices. I can't seem to find a good example in the book I recently got.
I just can't imagine that it is good practice to tell my domain object code to behave like it is in a transaction when there could be times when it isn't.
Can anyone show me the light on what I need to do to fix this correctly?
Ok so there were a lot of things I needed to change with this. But one of the glaring problems with this situation is that I have the connection being used in the using statement. Which as soon as it exits out it is being disposed of. Since this transaction goes through several of these methods like this it turned out my connection and transaction were being disposed of after the first call.
I just had one of those duh moments right now and I realized it. I hate how sometimes the answer can be so obvious.
I am using the .xsd dataset thingies (which I hate) to auto-generate TableAdapter classes for some backend code.
I have not really used these before, tending to favour manual commands and stored procs whenever possible (for various speed-induced reasons: those xsds play hell with dynamic tables and really large amounts of columns), and am finding myself instantiating a TableAdapter in a large number of my methods, so my question is this:
Will the auto-generated code automatically streamline itself so that a full adapter class is not created on an instatiation, and instead share some static data (such as connection information), and if not would it be better for me to have some sort of singleton/static class provider that can give me access to their methods when needed without the overhead of creating a new adapter every time I want to get some information?
Cheers, Ed
If you're concerned about the performance you could always run a benchmark to see what the performance hit, if any, is.
Sorry you didn't find my answer useful.
My point was that while you had received responses they all seemed to be subjective and not based on hard data. So if you had some reason to be concerned that there was a performance hit in your particular application you should measure it.
There is no reason to refactor one area for performance unless there is an actual problem.
I actually tend to instanciate a very low number of adapters (usually only one of each type). I never tried using them as on the stack variables (instantiated when needed), so I never ran into your question, but I understand your concern.
From what I know the aqdapters themselves may be quite heavyweight in instancing, but the real killer is the connection. What I do is I mark the adapter's Connection modifier as Public in the .xsd designer so I can assign the property whatever I need it to use, and maintain a tight grip on the opening and closing of connections:
void Load() {
using (SqlConnection conn = ...) {
conn.Open();
invoicesAdapter.Connection = conn;
customersAdapter.Connection = conn;
invoicesAdapter.Fill(dataSet.Invoices);
customersAdapter.Fill(dataSet.Customers);
}
}
void Save() {
using (SqlConnection conn = ...) {
conn.Open();
invoicesAdapter.Connection = conn;
customersAdapter.Connection = conn;
invoicesAdapter.Update(dataSet);
customersAdapater.Update(dataSet);
}
}
I ommitted transaction control and error handling for brevity.
We have a SQL utility class that takes the name of a stored procedure an its input parameters, and returns the results in datatable. The reasoning behind this is so that we don't have to worry about forgetting to close connections and having connection leaks. Also so that we can reduce code by not having to recreate datadapters and datareaders in our data access layers.
The problem I have with this is that we're populating a datatable so that we can loop through it to create our objects, so we're basically using it like a datareader. I've read about classes that will return a datareader or dataadapter. But the problem with this is either client has to open and close connections, or you have to close the connection in a Finalize method. It seems that you wouldn't want garbage collection being responsible for closing your database connections.
To sum up, we want to have a class so that we can reduce code by not having to create datareaders for every query and so that we can ensure database connections are closed.
What is the best way of handling this?
UPDATE: Still thinking about this, but so far it seems that the best practice is to still return a datareader, use CommandBehavior.CloseConnection, and then trust who ever uses the class to call dr.Close()?
Have you considered the Microsoft Enterprise Library?
public List<User> GetUsers()
{
List<User> result = new List<User>();
Database db = new
Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase(this.connectionString);
DbCommand cmd = db.GetStoredProcCommand("GetUsers");
using (IDataReader rdr = db.ExecuteReader(cmd))
{
while (rdr.Read())
{
User user = new User();
FillUser(rdr, user);
result.Add(user);
}
}
return result;
}
We use something like this and it performs very well under high volume.
public SqlDataReader ExecuteReader(string command, SqlParameter[] parameters)
{
SqlDataReader reader = null;
using (SqlConnection conn = new SqlConnection())
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = command;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(parameters);
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
return reader;
}
DataTables are not considered best practice for several reasons including their bloat and lack of type safety.
I have the same structure - utility classes with methods that fetch the data and return filled DataTables (or fill/update a DataTable passed in to them) - for exactly the same reasons: keeping the database connections separate from the rest of the code and ensuring they are opened only when required and closed asap. Especially since the data is stored in various back-end systems, and I want to present only one interface to my application and not have it worry about the details.
There is one difference to your situation: We don't (in general) create objects from the rows in the DataTables, but rather work directly on the data in the rows. I find working with DataTables simple and efficient.
Other than that, I personally don't see anything wrong with this approach and find that it works very well for our purposes.
Returning a datareader doesn't work in a lot of scenarios. At a lot of places, direct connections to the database from the client machine are not allowed in production (for good reason). So you have to serialize the objects you are retrieving. I can think of designs that would allow you to persist a datareader in whatever class you use for remoting/serialization on the server side but returning items across http or nettcp in row by agonizing row fashion likely does not offer much benefit.
Are you serializing these objects? If so, your choices boil down to Datatable, Dataset, or custom objects. Custom objects, if written well, perform and serialize the best but you have to write concurrency in addition to a bunch of other functionality.
IMO, since ADO.Net 2.0, datatables can perform well even in large scale remoting situations. They provide a special binary remoting format and are simple to work with. Throw in some compression and you're not even using a lot of bandwidth for your large data sets.
well, if you plan to use this class inside of web pages you can register the utility class with the page's unload event. In the event sink you can write your logic to close the database connection. Check out this tip on codeproject for more ideas.
however this solution won't work for use inside web methods (web services). I suppose you'd have to adapt the technique for web service use. Your last line in the web method should should be an event call. So when you write your web service class, define an event called WebMethodCompleted. You'd probably get a reference to the instance of the web service via the technique mentioned in the article. Once you get a reference you can register tthe event in your utility class. Just remember to invoke the event in the web method.
Happy programming.