From ae9e0acef81eb996ac7e2f37f5cbee4aa8261d5c Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Fri, 5 Sep 2008 23:03:08 +0000 Subject: [PATCH] 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. --- .../jdbc/depot/DepotRepository.java | 71 ++++++++++++++----- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/src/java/com/samskivert/jdbc/depot/DepotRepository.java b/src/java/com/samskivert/jdbc/depot/DepotRepository.java index 93fdc97..38012d3 100644 --- a/src/java/com/samskivert/jdbc/depot/DepotRepository.java +++ b/src/java/com/samskivert/jdbc/depot/DepotRepository.java @@ -185,39 +185,72 @@ public abstract class DepotRepository /** * 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 List> findAllKeys ( - Class type, QueryClause... clause) + Class 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. + * + * @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 List> findAllKeys ( - Class type, Collection clauses) + Class type, boolean forUpdate, Collection clauses) { - // first look up the primary keys for all the rows that match our where clause + final List> keys = new ArrayList>(); final DepotMarshaller marsh = _ctx.getMarshaller(type); final SQLBuilder builder = _ctx.getSQLBuilder(DepotTypes.getDepotTypes(_ctx, clauses)); builder.newQuery(new SelectClause(type, marsh.getPrimaryKeyFields(), clauses)); - return _ctx.invoke(new Query.Trivial>>() { - @Override public List> invoke (Connection conn, DatabaseLiaison liaison) - throws SQLException { - List> keys = new ArrayList>(); - PreparedStatement stmt = builder.prepare(conn); - try { - ResultSet rs = stmt.executeQuery(); - while (rs.next()) { - keys.add(marsh.makePrimaryKey(rs)); + + if (forUpdate) { + _ctx.invoke(new Modifier(null) { + @Override + public int 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 0; + } finally { + JDBCUtil.close(stmt); } - return keys; - } finally { - JDBCUtil.close(stmt); } - } - }); + }); + + } else { + _ctx.invoke(new Query.Trivial() { + @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 { // look up the primary keys for all rows matching our where clause and delete using those - KeySet pwhere = new KeySet(type, findAllKeys(type, where)); + KeySet pwhere = new KeySet(type, findAllKeys(type, true, where)); return deleteAll(type, pwhere, pwhere); }