#1504 - ENH: Add SqlUpdate executeNow() method ... that executes now regardless of transaction batch mode

This commit is contained in:
rob bygrave
2018-10-12 18:49:20 +13:00
parent 82e68d7756
commit b87e360ac7
9 changed files with 90 additions and 6 deletions
+10
View File
@@ -98,6 +98,11 @@ public interface SqlUpdate {
/**
* Execute the update returning the number of rows modified.
* <p>
* Note that if the transaction has batch mode on then this update will use JDBC batch and may not execute until
* later - at commit time or a transaction flush. In this case this method returns -1 indicating that the
* update has been batched for later execution.
* </p>
* <p>
* After you have executed the SqlUpdate you can bind new variables using
* {@link #setParameter(String, Object)} etc and then execute the SqlUpdate
* again.
@@ -112,6 +117,11 @@ public interface SqlUpdate {
*/
int execute();
/**
* Execute the statement now regardless of the JDBC batch mode of the transaction.
*/
int executeNow();
/**
* Execute when addBatch() has been used to batch multiple bind executions.
*
@@ -312,4 +312,8 @@ public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanLoader,
*/
int[] executeBatch(SpiSqlUpdate defaultSqlUpdate, SpiTransaction transaction);
/**
* Execute the sql update regardless of transaction batch mode.
*/
int executeNow(SpiSqlUpdate sqlUpdate);
}
@@ -2054,6 +2054,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return persister.executeSqlUpdate(updSql, t);
}
@Override
public int executeNow(SpiSqlUpdate sqlUpdate) {
return persister.executeSqlUpdateNow(sqlUpdate, null);
}
@Override
public void addBatch(SpiSqlUpdate sqlUpdate, SpiTransaction transaction) {
persister.addBatch(sqlUpdate, transaction);
@@ -133,6 +133,15 @@ public final class DefaultSqlUpdate implements Serializable, SpiSqlUpdate {
}
}
@Override
public int executeNow() {
if (server != null) {
return server.executeNow(this);
} else {
throw new IllegalStateException("server is null?");
}
}
@Override
public int[] executeBatch() {
if (server == null) {
@@ -28,18 +28,23 @@ public final class PersistRequestUpdateSql extends PersistRequest {
private boolean addBatch;
/**
* Create.
*/
private boolean forceNoBatch;
public PersistRequestUpdateSql(SpiEbeanServer server, SpiSqlUpdate sqlUpdate,
SpiTransaction t, PersistExecute persistExecute) {
SpiTransaction t, PersistExecute persistExecute, boolean forceNoBatch) {
super(server, t, persistExecute, sqlUpdate.getLabel());
this.type = Type.UPDATESQL;
this.updateSql = sqlUpdate;
this.forceNoBatch = forceNoBatch;
updateSql.reset();
}
public PersistRequestUpdateSql(SpiEbeanServer server, SpiSqlUpdate sqlUpdate,
SpiTransaction t, PersistExecute persistExecute) {
this(server, sqlUpdate, t, persistExecute, false);
}
@Override
public void profile(long offset, int flushCount) {
profileBase(EVT_UPDATESQL, offset, (short)0, flushCount);
@@ -60,7 +65,7 @@ public final class PersistRequestUpdateSql extends PersistRequest {
@Override
public boolean isBatchThisRequest() {
return addBatch || super.isBatchThisRequest();
return !forceNoBatch && (addBatch || super.isBatchThisRequest());
}
@Override
@@ -74,10 +74,15 @@ public interface Persister {
int executeOrmUpdate(Update<?> update, Transaction t);
/**
* Execute the UpdateSql.
* Execute the SqlUpdate (taking into account transaction batch mode).
*/
int executeSqlUpdate(SqlUpdate update, Transaction t);
/**
* Execute the SqlUpdate now regardless of transaction batch mode.
*/
int executeSqlUpdateNow(SpiSqlUpdate update, Transaction t);
/**
* Execute the CallableSql.
*/
@@ -150,6 +150,11 @@ public final class DefaultPersister implements Persister {
return executeOrQueue(new PersistRequestUpdateSql(server, (SpiSqlUpdate) updSql, (SpiTransaction) t, persistExecute));
}
@Override
public int executeSqlUpdateNow(SpiSqlUpdate updSql, Transaction t) {
return executeOrQueue(new PersistRequestUpdateSql(server, updSql, (SpiTransaction) t, persistExecute, true));
}
/**
* Restore draft beans to match live beans given the query.
*/
@@ -854,6 +854,11 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
return 0;
}
@Override
public int executeNow(SpiSqlUpdate sqlUpdate) {
return 0;
}
@Override
public void addBatch(SpiSqlUpdate sqlUpdate, SpiTransaction transaction) {
@@ -3,6 +3,7 @@ package org.tests.update;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import io.ebean.SqlUpdate;
import io.ebean.Transaction;
import io.ebean.meta.MetaTimedMetric;
import org.junit.Assert;
import org.junit.Test;
@@ -38,6 +39,41 @@ public class TestSqlUpdateInTxn extends BaseTestCase {
}
}
@Test
public void testExecute_inTransaction_withBatch() {
try (Transaction transaction = Ebean.beginTransaction()) {
transaction.setBatchMode(true);
int row = Ebean.createSqlUpdate("update audit_log set description = description where id = ?")
.setParameter(1, 999999)
.execute();
// update statement using JDBC batch so not executed yet
assertThat(row).isEqualTo(-1);
transaction.commit();
}
}
@Test
public void testExecuteNow_inTransaction_withBatch() {
try (Transaction transaction = Ebean.beginTransaction()) {
transaction.setBatchMode(true);
int row = Ebean.createSqlUpdate("update audit_log set description = description where id = ?")
.setParameter(1, 999999)
.executeNow();
// update statement executed even though JDBC batch mode is on
assertThat(row).isEqualTo(0);
transaction.commit();
}
}
@Test
public void testSqlUpdateWithWhitespace() {