From: <tho...@us...> - 2010-11-02 12:43:23
|
Revision: 3865 http://bigdata.svn.sourceforge.net/bigdata/?rev=3865&view=rev Author: thompsonbry Date: 2010-11-02 12:43:16 +0000 (Tue, 02 Nov 2010) Log Message: ----------- https://sourceforge.net/apps/trac/bigdata/ticket/187 I've updated the javadoc for ITransactionService#newTx(long) to indicate that the given timestamp may lie in the future. I've updated AbstractTransactionService? to hand back nextTimestamp() for a read-only transaction request when the given timestamp is in the future. I've updated TestTransactionService? to test this behavior for read-only and read-write tx (nothing had to be changed to support the latter). I've updated test_newTx_readOnly_timestampInFuture to request a timestamp which is known to be in the future and to verify that a read-only tx was assigned. These edits are self-consistent, but the tx semantics really ought to be reviewed in more depth, e.g., as part of https://sourceforge.net/apps/trac/bigdata/ticket/145 or when adding full-distributed read-write tx support to the database. Modified Paths: -------------- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/journal/ITransactionService.java branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/service/AbstractTransactionService.java branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/journal/TestTransactionService.java Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/journal/ITransactionService.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/journal/ITransactionService.java 2010-11-02 12:42:22 UTC (rev 3864) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/journal/ITransactionService.java 2010-11-02 12:43:16 UTC (rev 3865) @@ -152,9 +152,6 @@ * @return The unique transaction identifier. * * @throws IllegalStateException - * if the requested timestamp is greater than - * {@link #getLastCommitTime()}. - * @throws IllegalStateException * if the requested timestamp is for a commit point that is no * longer preserved by the database (the resources for that * commit point have been released). @@ -164,6 +161,9 @@ * @todo specialize exception for a timestamp that is no longer preserved * and for one that is in the future? */ +// * @throws IllegalStateException +// * if the requested timestamp is greater than +// * {@link #getLastCommitTime()}. public long newTx(long timestamp) throws IOException; /** Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/service/AbstractTransactionService.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/service/AbstractTransactionService.java 2010-11-02 12:42:22 UTC (rev 3864) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/java/com/bigdata/service/AbstractTransactionService.java 2010-11-02 12:43:16 UTC (rev 3865) @@ -625,6 +625,8 @@ private volatile long lastTimestamp; /** + * {@inheritDoc} + * <p> * Note: There is an upper bound of one read-write transaction that may be * created per millisecond (the resolution of {@link #nextTimestamp()}) and * requests for new read-write transactions contend with other requests for @@ -1234,21 +1236,21 @@ final long lastCommitTime = getLastCommitTime(); -// if (timestamp > lastCommitTime) { - if (timestamp > lastTimestamp) { - - /* - * You can't request a historical read for a timestamp which has not - * yet been issued by this service! - */ +// if (timestamp > lastTimestamp) { +// +// /* +// * You can't request a historical read for a timestamp which has not +// * yet been issued by this service! +// */ +// +// throw new IllegalStateException( +// "Timestamp is in the future: timestamp=" + timestamp +// + ", lastCommitTime=" + lastCommitTime +// + ", lastTimestamp=" + lastTimestamp); +// +// } else + if (timestamp == lastCommitTime) { - throw new IllegalStateException( - "Timestamp is in the future: timestamp=" + timestamp - + ", lastCommitTime=" + lastCommitTime - + ", lastTimestamp=" + lastTimestamp); - - } else if (timestamp == lastCommitTime) { - /* * Special case. We just return the next timestamp. * @@ -1325,12 +1327,23 @@ if (commitTime == -1L) { /* - * @todo I believe that this can only arise when there are no commit - * points in the log. + * There are no commit points in the log. + * + * Note: Just return the next timestamp. It is guaranteed to be GT + * the desired commit time (which does not exist) and LT the next + * commit point. */ - throw new RuntimeException( - "No data for that commit time: timestamp=" + timestamp); + return nextTimestamp(); + +// /* +// * Note: I believe that this can only arise when there are no commit +// * points in the log. The thrown exception is per the top-level api +// * for ITransactionService#newTx(long). +// */ +// throw new IllegalStateException( +// "No data for that commit time: timestamp=" + timestamp); + } /* Modified: branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/journal/TestTransactionService.java =================================================================== --- branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/journal/TestTransactionService.java 2010-11-02 12:42:22 UTC (rev 3864) +++ branches/QUADS_QUERY_BRANCH/bigdata/src/test/com/bigdata/journal/TestTransactionService.java 2010-11-02 12:43:16 UTC (rev 3865) @@ -270,8 +270,15 @@ @Override public long nextTimestamp() { - super.nextTimestamp () ; - return super.nextTimestamp () ; + // skip at least one millisecond. + super.nextTimestamp(); + + /* + * Invoke the behavior on the base class, which has a side-effect on + * the private [lastTimestamp] method. + */ + return super.nextTimestamp(); + } } @@ -889,33 +896,96 @@ } } + + /** + * Verify the behavior of the {@link AbstractTransactionService} when there + * are no commit points and a read-only transaction is requested. Since + * there are no commit points, the transaction service will return the next + * timestamp. That value will be GT the requested timestamp and LT any + * commit point (all commit points are in the future). + */ + public void test_newTx_nothingCommitted_readOnlyTx() { + final MockTransactionService service = newFixture(); + + try { + + /* + * Note: The commit time log is empty. + */ + final long timestamp = service.nextTimestamp(); + + /* + * Request a read-only view which is in the past based on the + * transaction server's clock. However, there are no commit points + * which cover that timestamp since there are no commit points in + * the database. + */ + service.newTx(timestamp - 1); + + } finally { + + service.destroy(); + + } + + } + /** - * Verify that you can not create a read-only transaction using a timestamp - * that is in the future. + * Verify the behavior of the {@link AbstractTransactionService} when there + * are no commit points and a read-write transaction is requested. You can + * always obtain a read-write transaction, even when there are no commit + * points on the database. */ - public void test_newTx_readOnly_timestampInFuture() { + public void test_newTx_nothingCommitted_readWriteTx() { final MockTransactionService service = newFixture(); try { /* - * Note: The commit time log is empty so anything is in the future. + * Note: The commit time log is empty. */ + service.newTx(ITx.UNISOLATED); + + } finally { - try { - /** - * FIXME Modified to be compatible with changes made to AbstractTransactionService, revision 3804. - * @see <a href="https://sourceforge.net/apps/trac/bigdata/ticket/187">Trac 187</a> - */ -// service.newTx(10); - service.newTx(service.nextTimestamp () + 10); - fail("Expecting: "+IllegalStateException.class); - } catch(IllegalStateException ex) { - log.info("Ignoring expected exception: "+ex); - } + service.destroy(); + + } + + } + + /** + * Verify that you can create a read-only transaction using a timestamp that + * is in the future. A commit point is generated and a read-only tx is + * requested which is beyond that commit point. The returned tx will be + * assigned using nextTimestamp() which is guaranteed to be less than the + * next commit point on the database (which in this case would be the first + * commit point as well). + */ + public void test_newTx_readOnly_timestampInFuture() { + + final MockTransactionService service = newFixture(); + + try { + + // request a timestamp. + final long timestamp1 = service.nextTimestamp(); + // make that timestamp a valid commit time. + service.notifyCommit(timestamp1); + +// try { + // request a timestamp in the future. + final long tx = service.newTx(timestamp1 * 2); + System.err.println("ts="+timestamp1); + System.err.println("tx="+tx); +// fail("Expecting: "+IllegalStateException.class); +// } catch(IllegalStateException ex) { +// log.info("Ignoring expected exception: "+ex); +// } + } finally { service.destroy(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |