mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-08 02:24:18 +00:00
Eliminate most unnecessary changes to the database when values haven't been altered (reduces contention, and unnecessary constraint validation)
git-svn-id: http://scm.dspace.org/svn/repo/branches/dspace-1_5_x@2639 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
@@ -632,22 +632,32 @@ public class DatabaseManager
|
|||||||
StringBuffer sql = new StringBuffer().append("update ").append(table)
|
StringBuffer sql = new StringBuffer().append("update ").append(table)
|
||||||
.append(" set ");
|
.append(" set ");
|
||||||
|
|
||||||
|
List columns = new ArrayList();
|
||||||
ColumnInfo pk = getPrimaryKeyColumnInfo(table);
|
ColumnInfo pk = getPrimaryKeyColumnInfo(table);
|
||||||
ColumnInfo[] info = getNonPrimaryKeyColumns(table);
|
ColumnInfo[] info = getNonPrimaryKeyColumns(table);
|
||||||
|
|
||||||
|
String seperator = "";
|
||||||
for (int i = 0; i < info.length; i++)
|
for (int i = 0; i < info.length; i++)
|
||||||
{
|
{
|
||||||
sql.append((i == 0) ? "" : ", ").append(info[i].getName()).append(
|
// Only update this column if it has changed
|
||||||
" = ?");
|
if (row.hasColumnChanged(info[i].getName()))
|
||||||
|
{
|
||||||
|
sql.append(seperator).append(info[i].getName()).append(" = ?");
|
||||||
|
columns.add(info[i]);
|
||||||
|
seperator = ", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sql.append(" where ").append(pk.getName()).append(" = ?");
|
// Only execute the update if there is anything to update
|
||||||
|
if (columns.size() > 0)
|
||||||
|
{
|
||||||
|
sql.append(" where ").append(pk.getName()).append(" = ?");
|
||||||
|
columns.add(pk);
|
||||||
|
|
||||||
List columns = new ArrayList();
|
return execute(context.getDBConnection(), sql.toString(), columns, row);
|
||||||
columns.addAll(Arrays.asList(info));
|
}
|
||||||
columns.add(pk);
|
|
||||||
|
|
||||||
return execute(context.getDBConnection(), sql.toString(), columns, row);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1107,6 +1117,8 @@ public class DatabaseManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now that we've prepped the TableRow, reset the flags so that we can detect which columns have changed
|
||||||
|
row.resetChanged();
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -67,6 +67,8 @@ public class TableRow
|
|||||||
*/
|
*/
|
||||||
private Map data = new HashMap();
|
private Map data = new HashMap();
|
||||||
|
|
||||||
|
private Map changed = new HashMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@@ -82,6 +84,7 @@ public class TableRow
|
|||||||
{
|
{
|
||||||
this.table = table;
|
this.table = table;
|
||||||
nullColumns(columns);
|
nullColumns(columns);
|
||||||
|
resetChanged(columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,6 +110,18 @@ public class TableRow
|
|||||||
return data.get(canonicalize(column)) != null;
|
return data.get(canonicalize(column)) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if this row contains this column and the value has been updated.
|
||||||
|
*
|
||||||
|
* @param column
|
||||||
|
* The column name (case-insensitive)
|
||||||
|
* @return True if this row contains a column with this name.
|
||||||
|
*/
|
||||||
|
public boolean hasColumnChanged(String column)
|
||||||
|
{
|
||||||
|
return changed.get(canonicalize(column)) == Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the column is an SQL NULL.
|
* Return true if the column is an SQL NULL.
|
||||||
*
|
*
|
||||||
@@ -387,15 +402,26 @@ public class TableRow
|
|||||||
throw new IllegalArgumentException("No such column " + column);
|
throw new IllegalArgumentException("No such column " + column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String canonName = canonicalize(column);
|
||||||
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
|
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
|
||||||
{
|
{
|
||||||
// if oracle, use 1 or 0 for true/false
|
// if oracle, use 1 or 0 for true/false
|
||||||
data.put(canonicalize(column), b ? new Integer(1) : new Integer(0));
|
Integer value = b ? new Integer(1) : new Integer(0);
|
||||||
|
if (!value.equals(data.get(canonName)))
|
||||||
|
{
|
||||||
|
data.put(canonName, value);
|
||||||
|
changed.put(canonName, Boolean.TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// default to postgres true/false
|
// default to postgres true/false
|
||||||
data.put(canonicalize(column), b ? Boolean.TRUE : Boolean.FALSE);
|
Boolean value = b ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
if (!value.equals(data.get(canonName)))
|
||||||
|
{
|
||||||
|
data.put(canonName, value);
|
||||||
|
changed.put(canonName, Boolean.TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,7 +442,13 @@ public class TableRow
|
|||||||
throw new IllegalArgumentException("No such column " + column);
|
throw new IllegalArgumentException("No such column " + column);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.put(canonicalize(column), (s == null) ? NULL_OBJECT : s);
|
String canonName = canonicalize(column);
|
||||||
|
Object value = (s == null) ? NULL_OBJECT : s;
|
||||||
|
if (!value.equals(data.get(canonName)))
|
||||||
|
{
|
||||||
|
data.put(canonName, value);
|
||||||
|
changed.put(canonName, Boolean.TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -436,7 +468,13 @@ public class TableRow
|
|||||||
throw new IllegalArgumentException("No such column " + column);
|
throw new IllegalArgumentException("No such column " + column);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.put(canonicalize(column), new Integer(i));
|
String canonName = canonicalize(column);
|
||||||
|
Integer value = new Integer(i);
|
||||||
|
if (!value.equals(data.get(canonName)))
|
||||||
|
{
|
||||||
|
data.put(canonName, value);
|
||||||
|
changed.put(canonName, Boolean.TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -456,7 +494,13 @@ public class TableRow
|
|||||||
throw new IllegalArgumentException("No such column " + column);
|
throw new IllegalArgumentException("No such column " + column);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.put(canonicalize(column), new Long(l));
|
String canonName = canonicalize(column);
|
||||||
|
Long value = new Long(l);
|
||||||
|
if (!value.equals(data.get(canonName)))
|
||||||
|
{
|
||||||
|
data.put(canonName, value);
|
||||||
|
changed.put(canonName, Boolean.TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -477,14 +521,13 @@ public class TableRow
|
|||||||
throw new IllegalArgumentException("No such column " + column);
|
throw new IllegalArgumentException("No such column " + column);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d == null)
|
String canonName = canonicalize(column);
|
||||||
|
Object value = (d == null) ? NULL_OBJECT : d;
|
||||||
|
if (!value.equals(data.get(canonName)))
|
||||||
{
|
{
|
||||||
setColumnNull(canonicalize(column));
|
data.put(canonName, value);
|
||||||
|
changed.put(canonName, Boolean.TRUE);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.put(canonicalize(column), d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
@@ -583,6 +626,29 @@ public class TableRow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetChanged(List columns)
|
||||||
|
{
|
||||||
|
for (Iterator iterator = columns.iterator(); iterator.hasNext();)
|
||||||
|
{
|
||||||
|
changed.put(canonicalize((String) iterator.next()), Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* package private method to reset the flags of which columns have been updated
|
||||||
|
* This is used by the database manager after it has finished processing the contents
|
||||||
|
* of a resultset, so that it can update only columns that have been updated.
|
||||||
|
* Note that this method does not reset the values themselves, only the flags,
|
||||||
|
* and should not be considered safe to call from anywhere other than the DatabaseManager.
|
||||||
|
*/
|
||||||
|
void resetChanged()
|
||||||
|
{
|
||||||
|
for (Iterator iterator = changed.keySet().iterator(); iterator.hasNext();)
|
||||||
|
{
|
||||||
|
changed.put(canonicalize((String) iterator.next()), Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal method to set column to null. The public method ensures that
|
* Internal method to set column to null. The public method ensures that
|
||||||
* column actually exists.
|
* column actually exists.
|
||||||
@@ -591,6 +657,11 @@ public class TableRow
|
|||||||
*/
|
*/
|
||||||
private void setColumnNullInternal(String column)
|
private void setColumnNullInternal(String column)
|
||||||
{
|
{
|
||||||
data.put(canonicalize(column), NULL_OBJECT);
|
String canonName = canonicalize(column);
|
||||||
|
if (data.get(canonName) != NULL_OBJECT)
|
||||||
|
{
|
||||||
|
data.put(canonName, NULL_OBJECT);
|
||||||
|
changed.put(canonName, Boolean.TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user