We need to let you express whether or not you want your keys from the master

server or if it's OK to get them from a (potentially slightly out of date)
replica. If you're going to modify rows based on the results of findAllKeys(),
you should probably get them from the master server, if you're just reading
data, you can talk to a replica.
This commit is contained in:
Michael Bayne
2008-09-05 23:03:08 +00:00
parent 2e4decf18a
commit ae9e0acef8
@@ -185,39 +185,72 @@ public abstract class DepotRepository
/** /**
* Looks up and returns {@link Key} records for all rows that match the supplied query clauses. * Looks up and returns {@link Key} records for all rows that match the supplied query clauses.
*
* @param forUpdate if true, the query will be run using a read-write connection to ensure that
* it talks to the master database, if false, the query will be run on a read-only connection
* and may load keys from a slave. For performance reasons, you should always pass false unless
* you know you will be modifying the database as a result of this query and absolutely need
* the latest data.
*/ */
protected <T extends PersistentRecord> List<Key<T>> findAllKeys ( protected <T extends PersistentRecord> List<Key<T>> findAllKeys (
Class<T> type, QueryClause... clause) Class<T> type, boolean forUpdate, QueryClause... clause)
{ {
return findAllKeys(type, Arrays.asList(clause)); return findAllKeys(type, forUpdate, Arrays.asList(clause));
} }
/** /**
* Looks up and returns {@link Key} records for all rows that match the supplied query clauses. * Looks up and returns {@link Key} records for all rows that match the supplied query clauses.
*
* @param forUpdate if true, the query will be run using a read-write connection to ensure that
* it talks to the master database, if false, the query will be run on a read-only connection
* and may load keys from a slave. For performance reasons, you should always pass false unless
* you know you will be modifying the database as a result of this query and absolutely need
* the latest data.
*/ */
protected <T extends PersistentRecord> List<Key<T>> findAllKeys ( protected <T extends PersistentRecord> List<Key<T>> findAllKeys (
Class<T> type, Collection<? extends QueryClause> clauses) Class<T> type, boolean forUpdate, Collection<? extends QueryClause> clauses)
{ {
// first look up the primary keys for all the rows that match our where clause final List<Key<T>> keys = new ArrayList<Key<T>>();
final DepotMarshaller<T> marsh = _ctx.getMarshaller(type); final DepotMarshaller<T> marsh = _ctx.getMarshaller(type);
final SQLBuilder builder = _ctx.getSQLBuilder(DepotTypes.getDepotTypes(_ctx, clauses)); final SQLBuilder builder = _ctx.getSQLBuilder(DepotTypes.getDepotTypes(_ctx, clauses));
builder.newQuery(new SelectClause<T>(type, marsh.getPrimaryKeyFields(), clauses)); builder.newQuery(new SelectClause<T>(type, marsh.getPrimaryKeyFields(), clauses));
return _ctx.invoke(new Query.Trivial<List<Key<T>>>() {
@Override public List<Key<T>> invoke (Connection conn, DatabaseLiaison liaison) if (forUpdate) {
throws SQLException { _ctx.invoke(new Modifier(null) {
List<Key<T>> keys = new ArrayList<Key<T>>(); @Override
PreparedStatement stmt = builder.prepare(conn); public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
try { PreparedStatement stmt = builder.prepare(conn);
ResultSet rs = stmt.executeQuery(); try {
while (rs.next()) { ResultSet rs = stmt.executeQuery();
keys.add(marsh.makePrimaryKey(rs)); while (rs.next()) {
keys.add(marsh.makePrimaryKey(rs));
}
return 0;
} finally {
JDBCUtil.close(stmt);
} }
return keys;
} finally {
JDBCUtil.close(stmt);
} }
} });
});
} else {
_ctx.invoke(new Query.Trivial<Void>() {
@Override
public Void invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
PreparedStatement stmt = builder.prepare(conn);
try {
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
keys.add(marsh.makePrimaryKey(rs));
}
return null;
} finally {
JDBCUtil.close(stmt);
}
}
});
}
return keys;
} }
/** /**
@@ -749,7 +782,7 @@ public abstract class DepotRepository
throws DatabaseException throws DatabaseException
{ {
// look up the primary keys for all rows matching our where clause and delete using those // look up the primary keys for all rows matching our where clause and delete using those
KeySet<T> pwhere = new KeySet<T>(type, findAllKeys(type, where)); KeySet<T> pwhere = new KeySet<T>(type, findAllKeys(type, true, where));
return deleteAll(type, pwhere, pwhere); return deleteAll(type, pwhere, pwhere);
} }