Compare commits

...
3 changed files with 44 additions and 1 deletions
@@ -84,6 +84,15 @@ public interface Update<T> {
*/
int execute();
/**
* Set an explicit transaction to use to execute this statement.
* <p>
* When not set, {@link #execute()} uses whatever transaction is currently active on
* the thread (or auto-commit if none is active) - consistent with
* {@link Database#execute(Update, Transaction)}.
*/
Update<T> usingTransaction(Transaction transaction);
/**
* Set an ordered bind parameter.
* <p>
@@ -1,6 +1,7 @@
package io.ebeaninternal.server.querydefn;
import io.ebean.Database;
import io.ebean.Transaction;
import io.ebean.Update;
import io.ebeaninternal.api.BindParams;
import io.ebeaninternal.api.SpiUpdate;
@@ -30,6 +31,7 @@ public final class DefaultOrmUpdate<T> implements SpiUpdate<T>, Serializable {
private String generatedSql;
private final String baseTable;
private final OrmUpdateType type;
private transient Transaction transaction;
/**
* Create with a specific server. This means you can use the
@@ -88,7 +90,13 @@ public final class DefaultOrmUpdate<T> implements SpiUpdate<T>, Serializable {
@Override
public int execute() {
return server.execute(this);
return server.execute(this, transaction);
}
@Override
public DefaultOrmUpdate<T> usingTransaction(Transaction transaction) {
this.transaction = transaction;
return this;
}
/**
@@ -1,6 +1,7 @@
package org.tests.basic;
import io.ebean.DB;
import io.ebean.Transaction;
import io.ebean.Update;
import io.ebean.xtest.BaseTestCase;
import org.junit.jupiter.api.AfterEach;
@@ -72,4 +73,29 @@ public class TestUpdate extends BaseTestCase {
Customer cust = DB.find(Customer.class).where().eq("name", "testUpdate3").findOne();
assertThat(cust.getSmallnote()).isEqualTo("Note #3");
}
@Test
public void testUsingTransaction_explicitNonAmbientTransaction() {
Update<Customer> update = DB.createUpdate(Customer.class,
"update customer set smallnote = :smallnote where name = :name")
.setParameter("name", "testUpdate1")
.setParameter("smallnote", "explicit txn note");
// ambient/current transaction on the thread - deliberately rolled back
try (Transaction ambient = DB.beginTransaction()) {
// explicit transaction - NOT the ambient/current one on the thread
try (Transaction explicit = DB.createTransaction()) {
update.usingTransaction(explicit);
int rows = update.execute();
assertThat(rows).isEqualTo(1);
explicit.commit();
}
// rolling back the ambient transaction does not affect the update - it ran
// against the explicit transaction which has already been committed above
ambient.rollback();
}
Customer cust = DB.find(Customer.class).where().eq("name", "testUpdate1").findOne();
assertThat(cust.getSmallnote()).isEqualTo("explicit txn note");
}
}