From 680231d7e79cae2636e9722ca12b79345fa2dbdd Mon Sep 17 00:00:00 2001
From: Melanie Thielker
Date: Thu, 23 Mar 2017 23:00:48 +0000
Subject: Make the MySqlGeneric layer transaction aware
---
OpenSim/Data/MySQL/MySQLFramework.cs | 75 ++++++++----
OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 163 ++++++++++++++++---------
2 files changed, 155 insertions(+), 83 deletions(-)
(limited to 'OpenSim/Data')
diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs
index 34791cf..93662db 100644
--- a/OpenSim/Data/MySQL/MySQLFramework.cs
+++ b/OpenSim/Data/MySQL/MySQLFramework.cs
@@ -36,7 +36,7 @@ using MySql.Data.MySqlClient;
namespace OpenSim.Data.MySQL
{
///
- /// A database interface class to a user profile storage system
+ /// Common code for a number of database modules
///
public class MySqlFramework
{
@@ -44,14 +44,24 @@ namespace OpenSim.Data.MySQL
log4net.LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- protected string m_connectionString;
- protected object m_dbLock = new object();
+ protected string m_connectionString = String.Empty;
+ protected MySqlTransaction m_trans = null;
+ // Constructor using a connection string. Instances constructed
+ // this way will open a new connection for each call.
protected MySqlFramework(string connectionString)
{
m_connectionString = connectionString;
}
+ // Constructor using a connection object. Instances constructed
+ // this way will use the connection object and never create
+ // new connections.
+ protected MySqlFramework(MySqlTransaction trans)
+ {
+ m_trans = trans;
+ }
+
//////////////////////////////////////////////////////////////
//
// All non queries are funneled through one connection
@@ -59,33 +69,48 @@ namespace OpenSim.Data.MySQL
//
protected int ExecuteNonQuery(MySqlCommand cmd)
{
- lock (m_dbLock)
+ if (m_trans == null)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
- try
- {
- dbcon.Open();
- cmd.Connection = dbcon;
+ dbcon.Open();
+ return ExecuteNonQueryWithConnection(cmd, dbcon);
+ }
+ }
+ else
+ {
+ return ExecuteNonQueryWithTransaction(cmd, m_trans);
+ }
+ }
- try
- {
- return cmd.ExecuteNonQuery();
- }
- catch (Exception e)
- {
- m_log.Error(e.Message, e);
- m_log.Error(Environment.StackTrace.ToString());
- return 0;
- }
- }
- catch (Exception e)
- {
- m_log.Error(e.Message, e);
- return 0;
- }
+ private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
+ {
+ cmd.Transaction = trans;
+ return ExecuteNonQueryWithConnection(cmd, trans.Connection);
+ }
+
+ private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
+ {
+ try
+ {
+ cmd.Connection = dbcon;
+
+ try
+ {
+ return cmd.ExecuteNonQuery();
}
+ catch (Exception e)
+ {
+ m_log.Error(e.Message, e);
+ m_log.Error(Environment.StackTrace.ToString());
+ return 0;
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.Error(e.Message, e);
+ return 0;
}
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
index 6aae9c6..bd8bbd5 100644
--- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
+++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
@@ -53,14 +53,27 @@ namespace OpenSim.Data.MySQL
get { return GetType().Assembly; }
}
+ public MySQLGenericTableHandler(MySqlTransaction trans,
+ string realm, string storeName) : base(trans)
+ {
+ m_Realm = realm;
+
+ CommonConstruct(storeName);
+ }
+
public MySQLGenericTableHandler(string connectionString,
string realm, string storeName) : base(connectionString)
{
m_Realm = realm;
- m_connectionString = connectionString;
+ CommonConstruct(storeName);
+ }
+
+ protected void CommonConstruct(string storeName)
+ {
if (storeName != String.Empty)
{
+ // We always use a new connection for any Migrations
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
dbcon.Open();
@@ -111,6 +124,11 @@ namespace OpenSim.Data.MySQL
public virtual T[] Get(string[] fields, string[] keys)
{
+ return Get(fields, keys, String.Empty);
+ }
+
+ public virtual T[] Get(string[] fields, string[] keys, string options)
+ {
if (fields.Length != keys.Length)
return new T[0];
@@ -126,8 +144,8 @@ namespace OpenSim.Data.MySQL
string where = String.Join(" and ", terms.ToArray());
- string query = String.Format("select * from {0} where {1}",
- m_Realm, where);
+ string query = String.Format("select * from {0} where {1} {2}",
+ m_Realm, where, options);
cmd.CommandText = query;
@@ -137,72 +155,92 @@ namespace OpenSim.Data.MySQL
protected T[] DoQuery(MySqlCommand cmd)
{
+ if (m_trans == null)
+ {
+ using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
+ {
+ dbcon.Open();
+
+ return DoQueryWithConnection(cmd, dbcon);
+ }
+ }
+ else
+ {
+ return DoQueryWithTransaction(cmd, m_trans);
+ }
+ }
+
+ protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
+ {
+ cmd.Transaction = trans;
+
+ return DoQueryWithConnection(cmd, trans.Connection);
+ }
+
+ protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
+ {
List result = new List();
- using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
+ cmd.Connection = dbcon;
+
+ using (IDataReader reader = cmd.ExecuteReader())
{
- dbcon.Open();
- cmd.Connection = dbcon;
+ if (reader == null)
+ return new T[0];
- using (IDataReader reader = cmd.ExecuteReader())
- {
- if (reader == null)
- return new T[0];
+ CheckColumnNames(reader);
- CheckColumnNames(reader);
+ while (reader.Read())
+ {
+ T row = new T();
- while (reader.Read())
+ foreach (string name in m_Fields.Keys)
{
- T row = new T();
-
- foreach (string name in m_Fields.Keys)
+ if (reader[name] is DBNull)
{
- if (reader[name] is DBNull)
- {
- continue;
- }
- if (m_Fields[name].FieldType == typeof(bool))
- {
- int v = Convert.ToInt32(reader[name]);
- m_Fields[name].SetValue(row, v != 0 ? true : false);
- }
- else if (m_Fields[name].FieldType == typeof(UUID))
- {
- m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
- }
- else if (m_Fields[name].FieldType == typeof(int))
- {
- int v = Convert.ToInt32(reader[name]);
- m_Fields[name].SetValue(row, v);
- }
- else if (m_Fields[name].FieldType == typeof(uint))
- {
- uint v = Convert.ToUInt32(reader[name]);
- m_Fields[name].SetValue(row, v);
- }
- else
- {
- m_Fields[name].SetValue(row, reader[name]);
- }
+ continue;
}
-
- if (m_DataField != null)
+ if (m_Fields[name].FieldType == typeof(bool))
+ {
+ int v = Convert.ToInt32(reader[name]);
+ m_Fields[name].SetValue(row, v != 0 ? true : false);
+ }
+ else if (m_Fields[name].FieldType == typeof(UUID))
+ {
+ m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
+ }
+ else if (m_Fields[name].FieldType == typeof(int))
+ {
+ int v = Convert.ToInt32(reader[name]);
+ m_Fields[name].SetValue(row, v);
+ }
+ else if (m_Fields[name].FieldType == typeof(uint))
+ {
+ uint v = Convert.ToUInt32(reader[name]);
+ m_Fields[name].SetValue(row, v);
+ }
+ else
{
- Dictionary data =
- new Dictionary();
+ m_Fields[name].SetValue(row, reader[name]);
+ }
+ }
- foreach (string col in m_ColumnNames)
- {
- data[col] = reader[col].ToString();
- if (data[col] == null)
- data[col] = String.Empty;
- }
+ if (m_DataField != null)
+ {
+ Dictionary data =
+ new Dictionary();
- m_DataField.SetValue(row, data);
+ foreach (string col in m_ColumnNames)
+ {
+ data[col] = reader[col].ToString();
+ if (data[col] == null)
+ data[col] = String.Empty;
}
- result.Add(row);
+ m_DataField.SetValue(row, data);
}
+
+ result.Add(row);
}
}
@@ -357,14 +395,23 @@ namespace OpenSim.Data.MySQL
public object DoQueryScalar(MySqlCommand cmd)
{
- using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
+ if (m_trans == null)
{
- dbcon.Open();
- cmd.Connection = dbcon;
+ using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
+ {
+ dbcon.Open();
+ cmd.Connection = dbcon;
+
+ return cmd.ExecuteScalar();
+ }
+ }
+ else
+ {
+ cmd.Connection = m_trans.Connection;
+ cmd.Transaction = m_trans;
return cmd.ExecuteScalar();
}
}
-
}
}
--
cgit v1.1