Bugfix: store() should never throw a DuplicateKeyException.
It would be extremely rare, but if two nodes were trying to simultaneously store() the same record with the same Key, one could fail with a DKE. Attempt a second 'update' if the insert fails.
This commit is contained in:
@@ -553,9 +553,12 @@ public abstract class DepotRepository
|
||||
}
|
||||
|
||||
final boolean[] created = new boolean[1];
|
||||
try {
|
||||
_ctx.invoke(new CachingModifier<T>(record, key, key) {
|
||||
@Override
|
||||
protected int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||
protected int invoke (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException
|
||||
{
|
||||
if (_key != null) {
|
||||
// run the update
|
||||
int mods = builder.prepare(conn).executeUpdate();
|
||||
@@ -590,6 +593,27 @@ public abstract class DepotRepository
|
||||
stats.noteModification(pClass);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (DuplicateKeyException dke) {
|
||||
if (key == null) {
|
||||
throw dke; // how would this even happen?
|
||||
}
|
||||
// this should be very rare: the insert failed. Retry one more update.
|
||||
_ctx.invoke(new CachingModifier<T>(record, key, key) {
|
||||
@Override
|
||||
protected int invoke (Connection conn, DatabaseLiaison liaison)
|
||||
throws SQLException
|
||||
{
|
||||
builder.newQuery(update);
|
||||
return builder.prepare(conn).executeUpdate();
|
||||
}
|
||||
@Override
|
||||
public void updateStats (Stats stats) {
|
||||
stats.noteModification(pClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return created[0];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user