#1239 - When Transaction.setSkipCache(true) ... Query with useQueryCache is still use L2 query cache

This commit is contained in:
Rob Bygrave
2018-01-19 10:46:49 +13:00
parent 13ddb915c8
commit 0a809b0fb3
5 changed files with 73 additions and 18 deletions
@@ -1124,6 +1124,9 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private <T> SpiOrmQueryRequest<T> createQueryRequest(SpiQuery<T> query, Transaction t) {
if (t == null) {
t = currentServerTransaction();
}
query.setDefaultRawSqlIfRequired();
if (query.isAutoTunable() && !autoTuneService.tuneQuery(query)) {
// use deployment FetchType.LAZY/EAGER annotations
@@ -1599,7 +1602,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
public List<SqlRow> findList(SqlQuery query, Transaction t) {
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, t);
try {
request.initTransIfRequired();
return request.findList();
@@ -255,19 +255,15 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
public void initTransIfRequired() {
// first check if the query requires its own transaction
if (transaction == null) {
// maybe a current one
transaction = ebeanServer.currentServerTransaction();
if (transaction == null) {
if (query.getType().isUpdate()) {
// bulk update or delete query
transaction = ebeanServer.beginServerTransaction();
} else {
// create an implicit transaction to execute this query
// potentially using read-only DataSource with autoCommit
transaction = ebeanServer.createQueryTransaction(query.getTenantId());
}
createdTransaction = true;
if (query.getType().isUpdate()) {
// bulk update or delete query
transaction = ebeanServer.beginServerTransaction();
} else {
// create an implicit transaction to execute this query
// potentially using read-only DataSource with autoCommit
transaction = ebeanServer.createQueryTransaction(query.getTenantId());
}
createdTransaction = true;
}
persistenceContext = getPersistenceContext(query, transaction);
loadContext = new DLoadContext(this, secondaryQueries);
@@ -527,8 +523,12 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
query.resetBeanCacheAutoMode(findOne);
}
public boolean isQueryCachePut() {
return cacheKey != null && query.getUseQueryCache().isPut();
}
public boolean isBeanCachePut() {
return query.isBeanCachePut();
return !transaction.isSkipCache() && query.isBeanCachePut();
}
/**
@@ -600,7 +600,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
@SuppressWarnings("unchecked")
public Object getFromQueryCache() {
if (query.getUseQueryCache() == CacheMode.OFF) {
if (query.getUseQueryCache() == CacheMode.OFF || (transaction != null && transaction.isSkipCache())) {
return null;
} else {
cacheKey = query.queryHash();
@@ -61,7 +61,7 @@ public final class RelationalQueryRequest {
/**
* Create the BeanFindRequest.
*/
public RelationalQueryRequest(SpiEbeanServer server, RelationalQueryEngine engine, SqlQuery q, Transaction t) {
RelationalQueryRequest(SpiEbeanServer server, RelationalQueryEngine engine, SqlQuery q, Transaction t) {
this.ebeanServer = server;
this.queryEngine = engine;
this.query = (SpiSqlQuery) q;
@@ -151,7 +151,7 @@ public class DefaultOrmQueryEngine implements OrmQueryEngine {
SpiQuery<T> query = request.getQuery();
if (query.isBeanCachePut()) {
if (request.isBeanCachePut()) {
// load the individual beans into the bean cache
BeanDescriptor<T> descriptor = request.getBeanDescriptor();
Collection<T> c = result.getActualDetails();
@@ -160,7 +160,7 @@ public class DefaultOrmQueryEngine implements OrmQueryEngine {
request.mergeCacheHits(result);
if (query.getUseQueryCache().isPut()) {
if (request.isQueryCachePut()) {
// load the query result into the query cache
result.setReadOnly(true);
request.putToQueryCache(result);
@@ -0,0 +1,53 @@
package org.tests.transaction;
import io.ebean.BaseTestCase;
import io.ebean.CacheMode;
import io.ebean.Ebean;
import io.ebean.Transaction;
import org.ebeantest.LoggedSqlCollector;
import org.junit.Test;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestTransactionSkipCache extends BaseTestCase {
private void findUseQueryCache() {
Ebean.find(Customer.class)
.setUseQueryCache(true)
.setBeanCacheMode(CacheMode.PUT)
.where().startsWith("name", "Rob")
.findList();
}
private void setup() {
ResetBasicData.reset();
// load into L2 query cache
findUseQueryCache();
}
@Test
public void skipL2QueryCache() {
setup();
Transaction transaction = Ebean.beginTransaction();
try {
transaction.setSkipCache(true);
LoggedSqlCollector.start();
findUseQueryCache();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).as("We didn't use the L2 query cache").hasSize(1);
} finally {
transaction.end();
}
}
}