More changes to the MySQL adapter. take advantage of pooling and run lock-free.
This should finally kill the "There is already an open data reader associated with this connection, which must be closed first" error that makes people's builds not save0.6.1-post-fixes
parent
07ee2c3504
commit
38380def17
|
@ -72,69 +72,10 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.CommandText = "delete from prims, primshapes using prims " +
|
||||
"left join primshapes on prims.uuid = primshapes.uuid " +
|
||||
"where PCode = 9 and State <> 0";
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
}
|
||||
|
||||
private IDataReader ExecuteReader(MySqlCommand c)
|
||||
{
|
||||
IDataReader r = null;
|
||||
bool errorSeen = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
r = c.ExecuteReader();
|
||||
}
|
||||
catch (MySqlException)
|
||||
{
|
||||
System.Threading.Thread.Sleep(500);
|
||||
|
||||
m_Connection.Close();
|
||||
m_Connection.Open();
|
||||
|
||||
if (!errorSeen)
|
||||
{
|
||||
errorSeen = true;
|
||||
continue;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private void ExecuteNonQuery(MySqlCommand c)
|
||||
{
|
||||
bool errorSeen = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
c.ExecuteNonQuery();
|
||||
}
|
||||
catch (MySqlException)
|
||||
{
|
||||
System.Threading.Thread.Sleep(500);
|
||||
|
||||
m_Connection.Close();
|
||||
m_Connection.Open();
|
||||
|
||||
if (!errorSeen)
|
||||
{
|
||||
errorSeen = true;
|
||||
continue;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {}
|
||||
|
@ -150,9 +91,10 @@ namespace OpenSim.Data.MySQL
|
|||
if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
|
||||
return;
|
||||
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
foreach (SceneObjectPart prim in obj.Children.Values)
|
||||
{
|
||||
|
@ -227,7 +169,7 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
cmd.Parameters.Clear();
|
||||
|
||||
|
@ -255,10 +197,10 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
FillShapeCommand(cmd, prim);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
}
|
||||
|
||||
public void RemoveObject(UUID obj, UUID regionUUID)
|
||||
|
@ -271,9 +213,10 @@ namespace OpenSim.Data.MySQL
|
|||
// cause the loss of a prim, but is cleaner.
|
||||
// It's also faster because it uses the primary key.
|
||||
//
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "select UUID from prims where "+
|
||||
"SceneGroupID= ?UUID";
|
||||
|
@ -282,11 +225,11 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
List<UUID> uuids = new List<UUID>();
|
||||
|
||||
IDataReader reader = ExecuteReader(cmd);
|
||||
IDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
try
|
||||
{
|
||||
while (reader.Read())
|
||||
while(reader.Read())
|
||||
{
|
||||
uuids.Add(new UUID(reader["UUID"].ToString()));
|
||||
}
|
||||
|
@ -296,18 +239,25 @@ namespace OpenSim.Data.MySQL
|
|||
reader.Close();
|
||||
}
|
||||
|
||||
foreach (UUID uuid in uuids)
|
||||
RemoveItems(uuid);
|
||||
|
||||
cmd.CommandText = "delete from prims where SceneGroupID= ?UUID";
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
cmd.CommandText = "delete from primshapes where UUID = ?UUID";
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.Dispose();
|
||||
foreach (UUID uuid in uuids)
|
||||
{
|
||||
cmd.Parameters.Clear();
|
||||
cmd.Parameters.AddWithValue("UUID", Util.ToRawUuidString(uuid));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
cmd.Dispose();
|
||||
c.Close();
|
||||
|
||||
foreach (UUID uuid in uuids)
|
||||
RemoveItems(uuid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -317,18 +267,19 @@ namespace OpenSim.Data.MySQL
|
|||
/// <param name="uuid">the Item UUID</param>
|
||||
private void RemoveItems(UUID uuid)
|
||||
{
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "delete from primitems where " +
|
||||
"PrimID = ?PrimID";
|
||||
|
||||
cmd.Parameters.AddWithValue("PrimID", uuid.ToString());
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
}
|
||||
|
||||
public List<SceneObjectGroup> LoadObjects(UUID regionUUID)
|
||||
|
@ -338,9 +289,10 @@ namespace OpenSim.Data.MySQL
|
|||
List<SceneObjectPart> prims = new List<SceneObjectPart>();
|
||||
SceneObjectGroup grp = null;
|
||||
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "select *, " +
|
||||
"case when prims.UUID = SceneGroupID " +
|
||||
|
@ -352,7 +304,7 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("RegionUUID",
|
||||
Util.ToRawUuidString(regionUUID));
|
||||
|
||||
IDataReader reader = ExecuteReader(cmd);
|
||||
IDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -402,7 +354,7 @@ namespace OpenSim.Data.MySQL
|
|||
if (grp != null)
|
||||
objects.Add(grp);
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
|
||||
foreach (SceneObjectPart part in prims)
|
||||
LoadItems(part);
|
||||
|
@ -418,16 +370,17 @@ namespace OpenSim.Data.MySQL
|
|||
/// <param name="prim">The prim</param>
|
||||
private void LoadItems(SceneObjectPart prim)
|
||||
{
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "select * from primitems where "+
|
||||
"PrimID = ?PrimID";
|
||||
|
||||
cmd.Parameters.AddWithValue("PrimID", prim.UUID.ToString());
|
||||
|
||||
IDataReader reader = ExecuteReader(cmd);
|
||||
IDataReader reader = cmd.ExecuteReader();
|
||||
List<TaskInventoryItem> inventory =
|
||||
new List<TaskInventoryItem>();
|
||||
|
||||
|
@ -448,24 +401,25 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
|
||||
cmd.Dispose();
|
||||
c.Close();
|
||||
prim.Inventory.RestoreInventoryItems(inventory);
|
||||
}
|
||||
}
|
||||
|
||||
public void StoreTerrain(double[,] ter, UUID regionID)
|
||||
{
|
||||
m_log.Info("[REGION DB]: Storing terrain");
|
||||
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "delete from terrain where " +
|
||||
"RegionUUID = ?RegionUUID";
|
||||
cmd.Parameters.AddWithValue("RegionUUID",
|
||||
Util.ToRawUuidString(regionID));
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
cmd.CommandText = "insert into terrain (RegionUUID, " +
|
||||
"Revision, Heightfield) values (?RegionUUID, " +
|
||||
|
@ -474,9 +428,9 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("Heightfield",
|
||||
SerializeTerrain(ter));
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
}
|
||||
|
||||
public double[,] LoadTerrain(UUID regionID)
|
||||
|
@ -484,15 +438,17 @@ namespace OpenSim.Data.MySQL
|
|||
double[,] terrain = new double[256,256];
|
||||
terrain.Initialize();
|
||||
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "select RegionUUID, Revision, Heightfield " +
|
||||
"from terrain where RegionUUID = ?RegionUUID "+
|
||||
"order by Revision desc limit 1";
|
||||
cmd.Parameters.AddWithValue("RegionUUID", Util.ToRawUuidString(regionID));
|
||||
|
||||
IDataReader reader = ExecuteReader(cmd);
|
||||
IDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -513,39 +469,44 @@ namespace OpenSim.Data.MySQL
|
|||
m_log.InfoFormat("[REGION DB]: Loaded terrain " +
|
||||
"revision r{0}", rev);
|
||||
|
||||
reader.Close();
|
||||
cmd.Dispose();
|
||||
c.Close();
|
||||
return terrain;
|
||||
}
|
||||
}
|
||||
finally
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveLandObject(UUID globalID)
|
||||
{
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "delete from land where UUID = ?UUID";
|
||||
|
||||
cmd.Parameters.AddWithValue("UUID", Util.ToRawUuidString(globalID));
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
}
|
||||
|
||||
public void StoreLandObject(ILandObject parcel)
|
||||
{
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "replace into land (UUID, RegionUUID, " +
|
||||
"LocalLandID, Bitmap, Name, Description, " +
|
||||
|
@ -570,12 +531,12 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
FillLandCommand(cmd, parcel.landData, parcel.regionUUID);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
cmd.CommandText = "delete from landaccesslist where " +
|
||||
"LandUUID = ?UUID";
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
cmd.Parameters.Clear();
|
||||
cmd.CommandText = "insert into landaccesslist (LandUUID, " +
|
||||
|
@ -586,26 +547,27 @@ namespace OpenSim.Data.MySQL
|
|||
parcel.landData.ParcelAccessList)
|
||||
{
|
||||
FillLandAccessCommand(cmd, entry, parcel.landData.GlobalID);
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Parameters.Clear();
|
||||
}
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
}
|
||||
|
||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
{
|
||||
RegionSettings rs = null;
|
||||
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "select * from regionsettings where " +
|
||||
"regionUUID = ?RegionUUID";
|
||||
cmd.Parameters.AddWithValue("regionUUID", regionUUID);
|
||||
|
||||
IDataReader reader = ExecuteReader(cmd);
|
||||
IDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -628,16 +590,17 @@ namespace OpenSim.Data.MySQL
|
|||
reader.Close();
|
||||
}
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
public void StoreRegionSettings(RegionSettings rs)
|
||||
{
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "replace into regionsettings (regionUUID, " +
|
||||
"block_terraform, block_fly, allow_damage, " +
|
||||
|
@ -672,18 +635,19 @@ namespace OpenSim.Data.MySQL
|
|||
|
||||
FillRegionSettingsCommand(cmd, rs);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
}
|
||||
|
||||
public List<LandData> LoadLandObjects(UUID regionUUID)
|
||||
{
|
||||
List<LandData> landData = new List<LandData>();
|
||||
|
||||
lock (m_Connection)
|
||||
{
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
cmd.CommandText = "select * from land where " +
|
||||
"RegionUUID = ?RegionUUID";
|
||||
|
@ -691,7 +655,7 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("RegionUUID",
|
||||
Util.ToRawUuidString(regionUUID));
|
||||
|
||||
IDataReader reader = ExecuteReader(cmd);
|
||||
IDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -716,7 +680,7 @@ namespace OpenSim.Data.MySQL
|
|||
cmd.Parameters.AddWithValue("LandUUID",
|
||||
Util.ToRawUuidString(land.GlobalID));
|
||||
|
||||
reader = ExecuteReader(cmd);
|
||||
reader = cmd.ExecuteReader();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -731,7 +695,7 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
}
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
|
||||
return landData;
|
||||
}
|
||||
|
@ -1414,12 +1378,13 @@ byte[] textureEntry = (byte[]) row["Texture"];
|
|||
}
|
||||
|
||||
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
|
||||
{
|
||||
lock (m_Connection)
|
||||
{
|
||||
RemoveItems(primID);
|
||||
|
||||
MySqlCommand cmd = m_Connection.CreateCommand();
|
||||
MySqlConnection c = (MySqlConnection) ((ICloneable)m_Connection).Clone();
|
||||
c.Open();
|
||||
|
||||
MySqlCommand cmd = c.CreateCommand();
|
||||
|
||||
if (items.Count == 0)
|
||||
return;
|
||||
|
@ -1446,10 +1411,10 @@ byte[] textureEntry = (byte[]) row["Texture"];
|
|||
|
||||
FillItemCommand(cmd, item);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
cmd.Dispose();
|
||||
}
|
||||
c.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue