diff --git a/jOOQ/src/main/java/org/jooq/ContextTransactionalCallable.java b/jOOQ/src/main/java/org/jooq/ContextTransactionalCallable.java new file mode 100644 index 0000000000..ff53c65751 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/ContextTransactionalCallable.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2009-2016, Data Geekery GmbH (http://www.datageekery.com) + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq; + +import org.jooq.impl.ThreadLocalTransactionProvider; + +/** + * An FunctionalInterface that wraps transactional code. + *

+ * This callable may depend on captured scope ("context") in order to discover a + * contextual {@link Configuration} to be used to create new SQL statements. + * Clients are responsible to implement such context state in appropriate + * {@link ConnectionProvider} and {@link TransactionProvider} implementations. + *

+ * An out-of-the-box implementation for a fitting {@link TransactionProvider} is + * available through {@link ThreadLocalTransactionProvider}. + * + * @author Lukas Eder + */ + +@FunctionalInterface + +public interface ContextTransactionalCallable { + + /** + * Run the transactional code. + *

+ * If this method completes normally, and this is not a nested transaction, + * then the transaction will be committed. If this method completes with an + * exception, then the transaction is rolled back to the beginning of this + * ContextTransactionalCallable. + * + * @return The outcome of the transaction. + * @throws Exception Any exception that will cause a rollback of the code + * contained in this transaction. If this is a nested + * transaction, the rollback may be performed only to the state + * before executing this + * ContextTransactionalCallable. + */ + T run() throws Exception; +} diff --git a/jOOQ/src/main/java/org/jooq/ContextTransactionalRunnable.java b/jOOQ/src/main/java/org/jooq/ContextTransactionalRunnable.java new file mode 100644 index 0000000000..1dd3bd4495 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/ContextTransactionalRunnable.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2009-2016, Data Geekery GmbH (http://www.datageekery.com) + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq; + +import org.jooq.impl.ThreadLocalTransactionProvider; + +/** + * An FunctionalInterface that wraps transactional code. + *

+ * This runnable may depend on captured scope ("context") in order to discover a + * contextual {@link Configuration} to be used to create new SQL statements. + * Clients are responsible to implement such context state in appropriate + * {@link ConnectionProvider} and {@link TransactionProvider} implementations. + *

+ * An out-of-the-box implementation for a fitting {@link TransactionProvider} is + * available through {@link ThreadLocalTransactionProvider}. + * + * @author Lukas Eder + */ + +@FunctionalInterface + +public interface ContextTransactionalRunnable { + + /** + * Run the transactional code. + *

+ * If this method completes normally, and this is not a nested transaction, + * then the transaction will be committed. If this method completes with an + * exception, then the transaction is rolled back to the beginning of this + * ContextTransactionalRunnable. + * + * @throws Exception Any exception that will cause a rollback of the code + * contained in this transaction. If this is a nested + * transaction, the rollback may be performed only to the state + * before executing this + * ContextTransactionalRunnable. + */ + void run() throws Exception; +} diff --git a/jOOQ/src/main/java/org/jooq/DSLContext.java b/jOOQ/src/main/java/org/jooq/DSLContext.java index 3155369dd5..820dca0468 100644 --- a/jOOQ/src/main/java/org/jooq/DSLContext.java +++ b/jOOQ/src/main/java/org/jooq/DSLContext.java @@ -273,6 +273,11 @@ public interface DSLContext extends Scope , AutoCloseable { * DSLContext's underlying {@link #configuration()}'s * {@link Configuration#transactionProvider()}, and return the * transactional's outcome. + *

+ * The argument transactional code should not capture any scope but derive + * its {@link Configuration} from the + * {@link TransactionalCallable#run(Configuration)} argument in order to + * create new statements. * * @param transactional The transactional code * @return The transactional outcome @@ -280,37 +285,56 @@ public interface DSLContext extends Scope , AutoCloseable { T transactionResult(TransactionalCallable transactional); /** - * Run a {@link ThreadLocalTransactionalRunnable} in the context of this + * Run a {@link ContextTransactionalRunnable} in the context of this * DSLContext's underlying {@link #configuration()}'s - * {@link ThreadLocalTransactionProvider}. + * {@link Configuration#transactionProvider()}, and return the + * transactional's outcome. + *

+ * The argument transactional code may capture scope to derive its + * {@link Configuration} from the "context" in order to create new + * statements. This context can be provided, for instance, by + * {@link ThreadLocalTransactionProvider} automatically. * * @param transactional The transactional code + * @return The transactional outcome * @throws ConfigurationException if the underlying - * {@link Configuration#transactionProvider()} is not a - * {@link ThreadLocalTransactionProvider}. + * {@link Configuration#transactionProvider()} is not able to + * provide context (i.e. currently, it is not a + * {@link ThreadLocalTransactionProvider}). */ - T transactionResult(ThreadLocalTransactionalCallable transactional) throws ConfigurationException; + T transactionResult(ContextTransactionalCallable transactional) throws ConfigurationException; /** * Run a {@link TransactionalRunnable} in the context of this * DSLContext's underlying {@link #configuration()}'s * {@link Configuration#transactionProvider()}. + *

+ * The argument transactional code should not capture any scope but derive + * its {@link Configuration} from the + * {@link TransactionalCallable#run(Configuration)} argument in order to + * create new statements. * * @param transactional The transactional code */ void transaction(TransactionalRunnable transactional); /** - * Run a {@link ThreadLocalTransactionalRunnable} in the context of this + * Run a {@link ContextTransactionalRunnable} in the context of this * DSLContext's underlying {@link #configuration()}'s - * {@link ThreadLocalTransactionProvider}. + * {@link Configuration#transactionProvider()}. + *

+ * The argument transactional code may capture scope to derive its + * {@link Configuration} from the "context" in order to create new + * statements. This context can be provided, for instance, by + * {@link ThreadLocalTransactionProvider} automatically. * * @param transactional The transactional code * @throws ConfigurationException if the underlying - * {@link Configuration#transactionProvider()} is not a - * {@link ThreadLocalTransactionProvider}. + * {@link Configuration#transactionProvider()} is not able to + * provide context (i.e. currently, it is not a + * {@link ThreadLocalTransactionProvider}). */ - void transaction(ThreadLocalTransactionalRunnable transactional) throws ConfigurationException; + void transaction(ContextTransactionalRunnable transactional) throws ConfigurationException; @@ -327,7 +351,8 @@ public interface DSLContext extends Scope , AutoCloseable { * * @param transactional The transactional code * @return The transactional outcome - * @throws ConfigurationException If this is run with a {@link ThreadLocalTransactionProvider}. + * @throws ConfigurationException If this is run with a + * {@link ThreadLocalTransactionProvider}. */ CompletionStage transactionResultAsync(TransactionalCallable transactional) throws ConfigurationException; @@ -343,7 +368,8 @@ public interface DSLContext extends Scope , AutoCloseable { * {@link Configuration#executorProvider()}. * * @param transactional The transactional code - * @throws ConfigurationException If this is run with a {@link ThreadLocalTransactionProvider}. + * @throws ConfigurationException If this is run with a + * {@link ThreadLocalTransactionProvider}. */ CompletionStage transactionAsync(TransactionalRunnable transactional) throws ConfigurationException; @@ -359,7 +385,8 @@ public interface DSLContext extends Scope , AutoCloseable { * * @param transactional The transactional code * @return The transactional outcome - * @throws ConfigurationException If this is run with a {@link ThreadLocalTransactionProvider}. + * @throws ConfigurationException If this is run with a + * {@link ThreadLocalTransactionProvider}. */ CompletionStage transactionResultAsync(Executor executor, TransactionalCallable transactional) throws ConfigurationException; @@ -374,7 +401,8 @@ public interface DSLContext extends Scope , AutoCloseable { * {@link Executor}. * * @param transactional The transactional code - * @throws ConfigurationException If this is run with a {@link ThreadLocalTransactionProvider}. + * @throws ConfigurationException If this is run with a + * {@link ThreadLocalTransactionProvider}. */ CompletionStage transactionAsync(Executor executor, TransactionalRunnable transactional) throws ConfigurationException; diff --git a/jOOQ/src/main/java/org/jooq/TransactionalCallable.java b/jOOQ/src/main/java/org/jooq/TransactionalCallable.java index 2b998d37de..27ff7c8c5c 100644 --- a/jOOQ/src/main/java/org/jooq/TransactionalCallable.java +++ b/jOOQ/src/main/java/org/jooq/TransactionalCallable.java @@ -42,6 +42,13 @@ package org.jooq; /** * An FunctionalInterface that wraps transactional code. + *

+ * Transactional code should not depend on any captured scope, but use the + * argument {@link Configuration} passed to the {@link #run(Configuration)} + * method to derive its transaction context. + *

+ * If transactional code needs to depend on captured scope ("context"), then + * {@link ContextTransactionalCallable} is a better fit. * * @author Lukas Eder */ diff --git a/jOOQ/src/main/java/org/jooq/TransactionalRunnable.java b/jOOQ/src/main/java/org/jooq/TransactionalRunnable.java index 44702e4a88..2f07e43bc8 100644 --- a/jOOQ/src/main/java/org/jooq/TransactionalRunnable.java +++ b/jOOQ/src/main/java/org/jooq/TransactionalRunnable.java @@ -42,6 +42,13 @@ package org.jooq; /** * An FunctionalInterface that wraps transactional code. + *

+ * Transactional code should not depend on any captured scope, but use the + * argument {@link Configuration} passed to the {@link #run(Configuration)} + * method to derive its transaction context. + *

+ * If transactional code needs to depend on captured scope ("context"), then + * {@link ContextTransactionalRunnable} is a better fit. * * @author Lukas Eder */ diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java index 62c141ed91..8fd634864c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java @@ -217,8 +217,8 @@ import org.jooq.Table; import org.jooq.TableField; import org.jooq.TableLike; import org.jooq.TableRecord; -import org.jooq.ThreadLocalTransactionalCallable; -import org.jooq.ThreadLocalTransactionalRunnable; +import org.jooq.ContextTransactionalCallable; +import org.jooq.ContextTransactionalRunnable; import org.jooq.TransactionProvider; import org.jooq.TransactionalCallable; import org.jooq.TransactionalRunnable; @@ -419,7 +419,7 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri // ------------------------------------------------------------------------- @Override - public T transactionResult(final ThreadLocalTransactionalCallable transactional) { + public T transactionResult(final ContextTransactionalCallable transactional) { TransactionProvider tp = configuration().transactionProvider(); if (!(tp instanceof ThreadLocalTransactionProvider)) @@ -507,8 +507,8 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri } @Override - public void transaction(final ThreadLocalTransactionalRunnable transactional) { - transactionResult(new ThreadLocalTransactionalCallable() { + public void transaction(final ContextTransactionalRunnable transactional) { + transactionResult(new ContextTransactionalCallable() { @Override public Void run() throws Exception { transactional.run();