mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +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)
|
||||
.append(" set ");
|
||||
|
||||
List columns = new ArrayList();
|
||||
ColumnInfo pk = getPrimaryKeyColumnInfo(table);
|
||||
ColumnInfo[] info = getNonPrimaryKeyColumns(table);
|
||||
|
||||
String seperator = "";
|
||||
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();
|
||||
columns.addAll(Arrays.asList(info));
|
||||
columns.add(pk);
|
||||
return execute(context.getDBConnection(), sql.toString(), columns, row);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -67,6 +67,8 @@ public class TableRow
|
||||
*/
|
||||
private Map data = new HashMap();
|
||||
|
||||
private Map changed = new HashMap();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -82,6 +84,7 @@ public class TableRow
|
||||
{
|
||||
this.table = table;
|
||||
nullColumns(columns);
|
||||
resetChanged(columns);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,6 +110,18 @@ public class TableRow
|
||||
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.
|
||||
*
|
||||
@@ -387,15 +402,26 @@ public class TableRow
|
||||
throw new IllegalArgumentException("No such column " + column);
|
||||
}
|
||||
|
||||
String canonName = canonicalize(column);
|
||||
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
|
||||
{
|
||||
// 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
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (d == null)
|
||||
String canonName = canonicalize(column);
|
||||
Object value = (d == null) ? NULL_OBJECT : d;
|
||||
if (!value.equals(data.get(canonName)))
|
||||
{
|
||||
setColumnNull(canonicalize(column));
|
||||
|
||||
return;
|
||||
data.put(canonName, value);
|
||||
changed.put(canonName, Boolean.TRUE);
|
||||
}
|
||||
|
||||
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
|
||||
* column actually exists.
|
||||
@@ -591,6 +657,11 @@ public class TableRow
|
||||
*/
|
||||
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