aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MSSQL/MSSQLManager.cs
diff options
context:
space:
mode:
authorCharles Krinke2008-07-17 13:43:31 +0000
committerCharles Krinke2008-07-17 13:43:31 +0000
commite8412dcd42f6478f70f587d534a92a948cd6dd93 (patch)
treee3f2d084da7f40bd453bf06fefa43241facc0f86 /OpenSim/Data/MSSQL/MSSQLManager.cs
parentmorphing OSHttpHandler interface into an abstract base class. adding (diff)
downloadopensim-SC-e8412dcd42f6478f70f587d534a92a948cd6dd93.zip
opensim-SC-e8412dcd42f6478f70f587d534a92a948cd6dd93.tar.gz
opensim-SC-e8412dcd42f6478f70f587d534a92a948cd6dd93.tar.bz2
opensim-SC-e8412dcd42f6478f70f587d534a92a948cd6dd93.tar.xz
Mantis#1736. Thank you kindly, StrawberryFride for a patch that:
Many issues with handling connections in MSSQL, have rearchitected to ensure that connections are always opened and closed in a timely fashion & disposed of cleanly, and removed unnecessary lock statements. SQL Server performance seems to have improved considerably as a result, and various timeout errors seem to have been fixed.
Diffstat (limited to '')
-rw-r--r--OpenSim/Data/MSSQL/MSSQLManager.cs141
1 files changed, 59 insertions, 82 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLManager.cs b/OpenSim/Data/MSSQL/MSSQLManager.cs
index e421c5d..fe4ca77 100644
--- a/OpenSim/Data/MSSQL/MSSQLManager.cs
+++ b/OpenSim/Data/MSSQL/MSSQLManager.cs
@@ -45,11 +45,6 @@ namespace OpenSim.Data.MSSQL
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 /// <summary> 47 /// <summary>
48 /// The database connection object
49 /// </summary>
50 private IDbConnection dbcon;
51
52 /// <summary>
53 /// Connection string for ADO.net 48 /// Connection string for ADO.net
54 /// </summary> 49 /// </summary>
55 private readonly string connectionString; 50 private readonly string connectionString;
@@ -57,11 +52,24 @@ namespace OpenSim.Data.MSSQL
57 public MSSQLManager(string dataSource, string initialCatalog, string persistSecurityInfo, string userId, 52 public MSSQLManager(string dataSource, string initialCatalog, string persistSecurityInfo, string userId,
58 string password) 53 string password)
59 { 54 {
60 connectionString = "Data Source=" + dataSource + ";Initial Catalog=" + initialCatalog + 55 SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
61 ";Persist Security Info=" + persistSecurityInfo + ";User ID=" + userId + ";Password=" + 56
62 password + ";"; 57 builder.DataSource = dataSource;
63 dbcon = new SqlConnection(connectionString); 58 builder.InitialCatalog = initialCatalog;
64 dbcon.Open(); 59 builder.PersistSecurityInfo = Convert.ToBoolean(persistSecurityInfo);
60 builder.UserID = userId;
61 builder.Password = password;
62 builder.ApplicationName = Assembly.GetEntryAssembly().Location;
63
64 connectionString = builder.ToString();
65 }
66
67 private SqlConnection createConnection()
68 {
69 SqlConnection conn = new SqlConnection(connectionString);
70 conn.Open();
71
72 return conn;
65 } 73 }
66 74
67 //private DataTable createRegionsTable() 75 //private DataTable createRegionsTable()
@@ -121,7 +129,7 @@ namespace OpenSim.Data.MSSQL
121 } 129 }
122 130
123 /// <summary> 131 /// <summary>
124 /// 132 /// Define Table function
125 /// </summary> 133 /// </summary>
126 /// <param name="dt"></param> 134 /// <param name="dt"></param>
127 /// <returns></returns> 135 /// <returns></returns>
@@ -178,35 +186,11 @@ namespace OpenSim.Data.MSSQL
178 } 186 }
179 } 187 }
180 188
181 /// <summary>
182 /// Shuts down the database connection
183 /// </summary>
184 public void Close()
185 {
186 dbcon.Close();
187 dbcon = null;
188 }
189 189
190 /// <summary> 190 private static readonly Dictionary<string, string> emptyDictionary = new Dictionary<string, string>();
191 /// Reconnects to the database 191 internal AutoClosingSqlCommand Query(string sql)
192 /// </summary>
193 public void Reconnect()
194 { 192 {
195 lock (dbcon) 193 return Query(sql, emptyDictionary);
196 {
197 try
198 {
199 // Close the DB connection
200 dbcon.Close();
201 // Try reopen it
202 dbcon = new SqlConnection(connectionString);
203 dbcon.Open();
204 }
205 catch (Exception e)
206 {
207 m_log.Error("Unable to reconnect to database " + e.ToString());
208 }
209 }
210 } 194 }
211 195
212 /// <summary> 196 /// <summary>
@@ -215,18 +199,20 @@ namespace OpenSim.Data.MSSQL
215 /// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param> 199 /// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param>
216 /// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param> 200 /// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param>
217 /// <returns>A Sql DB Command</returns> 201 /// <returns>A Sql DB Command</returns>
218 public IDbCommand Query(string sql, Dictionary<string, string> parameters) 202 internal AutoClosingSqlCommand Query(string sql, Dictionary<string, string> parameters)
219 { 203 {
220 SqlCommand dbcommand = (SqlCommand)dbcon.CreateCommand(); 204 SqlCommand dbcommand = createConnection().CreateCommand();
221 dbcommand.CommandText = sql; 205 dbcommand.CommandText = sql;
222 foreach (KeyValuePair<string, string> param in parameters) 206 foreach (KeyValuePair<string, string> param in parameters)
223 { 207 {
224 dbcommand.Parameters.AddWithValue(param.Key, param.Value); 208 dbcommand.Parameters.AddWithValue(param.Key, param.Value);
225 } 209 }
226 210
227 return (IDbCommand)dbcommand; 211 return new AutoClosingSqlCommand(dbcommand);
228 } 212 }
229 213
214
215
230 /// <summary> 216 /// <summary>
231 /// Runs a database reader object and returns a region row 217 /// Runs a database reader object and returns a region row
232 /// </summary> 218 /// </summary>
@@ -400,7 +386,6 @@ namespace OpenSim.Data.MSSQL
400 if (reader.Read()) 386 if (reader.Read())
401 { 387 {
402 // Region Main 388 // Region Main
403
404 asset = new AssetBase(); 389 asset = new AssetBase();
405 asset.Data = (byte[])reader["data"]; 390 asset.Data = (byte[])reader["data"];
406 asset.Description = (string)reader["description"]; 391 asset.Description = (string)reader["description"];
@@ -443,19 +428,20 @@ namespace OpenSim.Data.MSSQL
443 428
444 bool returnval = false; 429 bool returnval = false;
445 430
446 try 431 using (IDbCommand result = Query(sql, parameters))
447 { 432 {
448 IDbCommand result = Query(sql, parameters); 433 try
434 {
449 435
450 if (result.ExecuteNonQuery() == 1) 436 if (result.ExecuteNonQuery() == 1)
451 returnval = true; 437 returnval = true;
452 438
453 result.Dispose(); 439 }
454 } 440 catch (Exception e)
455 catch (Exception e) 441 {
456 { 442 m_log.Error(e.ToString());
457 m_log.Error(e.ToString()); 443 return false;
458 return false; 444 }
459 } 445 }
460 446
461 return returnval; 447 return returnval;
@@ -467,19 +453,12 @@ namespace OpenSim.Data.MSSQL
467 /// <param name="name">the ressource string</param> 453 /// <param name="name">the ressource string</param>
468 public void ExecuteResourceSql(string name) 454 public void ExecuteResourceSql(string name)
469 { 455 {
470 SqlCommand cmd = new SqlCommand(getResourceString(name), (SqlConnection)dbcon); 456 using (IDbCommand cmd = Query(getResourceString(name), new Dictionary<string,string>()))
471 cmd.ExecuteNonQuery(); 457 {
472 cmd.Dispose(); 458 cmd.ExecuteNonQuery();
459 }
473 } 460 }
474 461
475 /// <summary>
476 ///
477 /// </summary>
478 /// <returns>The actual SqlConnection</returns>
479 public SqlConnection getConnection()
480 {
481 return (SqlConnection)dbcon;
482 }
483 462
484 /// <summary> 463 /// <summary>
485 /// Given a list of tables, return the version of the tables, as seen in the database 464 /// Given a list of tables, return the version of the tables, as seen in the database
@@ -487,30 +466,29 @@ namespace OpenSim.Data.MSSQL
487 /// <param name="tableList"></param> 466 /// <param name="tableList"></param>
488 public void GetTableVersion(Dictionary<string, string> tableList) 467 public void GetTableVersion(Dictionary<string, string> tableList)
489 { 468 {
490 lock (dbcon) 469 Dictionary<string, string> param = new Dictionary<string, string>();
470 param["dbname"] = new SqlConnectionStringBuilder(connectionString).InitialCatalog;
471
472 using (IDbCommand tablesCmd =
473 Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG=@dbname", param))
474 using (IDataReader tables = tablesCmd.ExecuteReader())
491 { 475 {
492 Dictionary<string, string> param = new Dictionary<string, string>(); 476 while (tables.Read())
493 param["dbname"] = dbcon.Database;
494 IDbCommand tablesCmd =
495 Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG=@dbname", param);
496 using (IDataReader tables = tablesCmd.ExecuteReader())
497 { 477 {
498 while (tables.Read()) 478 try
499 { 479 {
500 try 480 string tableName = (string)tables["TABLE_NAME"];
501 { 481 if (tableList.ContainsKey(tableName))
502 string tableName = (string)tables["TABLE_NAME"]; 482 tableList[tableName] = tableName;
503 if (tableList.ContainsKey(tableName)) 483 }
504 tableList[tableName] = tableName; 484 catch (Exception e)
505 } 485 {
506 catch (Exception e) 486 m_log.Error(e.ToString());
507 {
508 m_log.Error(e.ToString());
509 }
510 } 487 }
511 tables.Close();
512 } 488 }
489 tables.Close();
513 } 490 }
491
514 } 492 }
515 493
516 /// <summary> 494 /// <summary>
@@ -546,7 +524,6 @@ namespace OpenSim.Data.MSSQL
546 // string dllName = module.Assembly.ManifestModule.Name; 524 // string dllName = module.Assembly.ManifestModule.Name;
547 Version dllVersion = module.Assembly.GetName().Version; 525 Version dllVersion = module.Assembly.GetName().Version;
548 526
549
550 return 527 return
551 string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, 528 string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
552 dllVersion.Revision); 529 dllVersion.Revision);