You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2016/05/09 17:01:16 UTC
svn commit: r1743006 - in /aries/site/trunk/content/modules/tx-control:
advancedResourceProviders.mdtext advancedScopes.mdtext
Author: timothyjward
Date: Mon May 9 17:01:16 2016
New Revision: 1743006
URL: http://svn.apache.org/viewvc?rev=1743006&view=rev
Log:
Fill in TODOs for the Transaction Control Service.
Modified:
aries/site/trunk/content/modules/tx-control/advancedResourceProviders.mdtext
aries/site/trunk/content/modules/tx-control/advancedScopes.mdtext
Modified: aries/site/trunk/content/modules/tx-control/advancedResourceProviders.mdtext
URL: http://svn.apache.org/viewvc/aries/site/trunk/content/modules/tx-control/advancedResourceProviders.mdtext?rev=1743006&r1=1743005&r2=1743006&view=diff
==============================================================================
--- aries/site/trunk/content/modules/tx-control/advancedResourceProviders.mdtext (original)
+++ aries/site/trunk/content/modules/tx-control/advancedResourceProviders.mdtext Mon May 9 17:01:16 2016
@@ -16,4 +16,130 @@ Notice: Licensed to the Apache Softwa
specific language governing permissions and limitations
under the License.
-#TODO
\ No newline at end of file
+#Making your own Resource Provider
+
+The <code>TransactionControl</code> service is based around the use of <code>ResourceProvider</code>
+instances. When combined the client receives a thread-safe resource instance that they can use.
+
+Resource Provider implementations already exist for [JDBC][1], [XA JDBC][2], [JPA][3] and [XA JPA][4]
+
+##Create an interface
+
+If you need to create your own Resource Provider then you should define a sub-interface which declares the
+type of the resource. This allows clients type-safe access to the resources, and makes it easier to identify
+the right Resource Provider at runtime.
+
+ public interface MyCustomResourceProvider extends
+ ResourceProvider<MyCustomResource> {}
+
+## Create an implementation
+
+The implementation of a ResourceProvider should return a thread-safe delegating proxy. This may be a
+dynamic proxy or a static one. The proxy delegates to the real resource, and is responsible for ensuring
+that the thread consistently accesses the same physical resource throughout the scope. Note that even
+when multiple proxies are created they should share the same physical resource throughout the life of the
+context.
+
+### Lifecycle - first access
+
+Whenever the resource is accessed then it must check to see whether it has already been accessed
+within the current scope. If not then a resource should be selected and associated with the scope. This
+physical resource must then be used for the rest of the scope.
+
+Note that if there is no active scope when the resource is accessed then the resource access should
+fail with a TransactionException.
+
+ /**
+ * A resource method
+ */
+ @Override
+ public boolean doSomething() {
+ if(!txControl.activeScope()) {
+ throw new TransactionException("There is no scope currently active");
+ }
+
+ // Locate, or create and associate
+ MyCustomResource delegate = locateDelegate(txControl.getCurrentContext());
+
+ return delegate.doSomething();
+ }
+
+### Lifecycle - enlisting
+
+If a transaction is active then the resource should enlist with it when it is first used. If the resource is
+usable with XA transactions then it should register an XAResource.
+
+ private MyCustomResource locateDelegate(TransactionContext context) {
+ MyCustomResource resource = findExisting(context);
+
+ if(resource != null) {
+ resource = getNewDelegate(context);
+
+ if(context.activeTransaction()) {
+ if(context.supportsXA()) {
+ context.registerXAResource(resource.getXAResource());
+ } else {
+ throw new TransactionException("The transaction does not support XA resources");
+ }
+ }
+ // Other resource preparation
+ ...
+ }
+
+ return resource;
+ }
+
+Local resources are similar, but they register a LocalResource, not an XAResource.
+
+ private MyCustomResource locateDelegate(TransactionContext context) {
+ MyCustomResource resource = findExisting(context);
+
+ if(resource != null) {
+ resource = getNewDelegate(context);
+
+ if(context.activeTransaction()) {
+ if(context.supportsLocal()) {
+ context.registerLocalResource(resource.getLocalesource());
+ } else {
+ throw new TransactionException("The transaction does not support Local resources");
+ }
+ }
+ // Other resource preparation
+ ...
+ }
+
+ return resource;
+ }
+
+### Lifecycle - Tidying up
+
+In addition to registering with an active transaction the resource should also register for cleanup at the end
+of the scope. This may involve closing the physical resource, or returning it to a pool.
+
+ // Other resource preparation
+
+ context.postCompletion(s -> resource.release());
+
+##Other things to look out for...
+
+1. A client must have a friendly way to access the ResourceProvider. This may be directly via the OSGi Service
+Registry or via a factory service of some kind.
+
+1. A resource must remain valid throughout a scope, therefore clients should not be able to close or return the
+resource by making calls on the thread-safe proxy. Typically calls to close should be a silent no-op (the
+actual close will occur when the scope ends).
+
+1. When a transaction is active clients must not be able to manually commit or rollback the resource.
+Methods like <code>commit</code>, <code>rollback</code> and <code>setRollbackOnly</code> must
+fail with a TransactionException indicating the incorrect usage. This is different from <code>close</code>
+behaviour because unlike deferring a <code>close</code> ignoring a <code>rollback</code> results in a
+different overall result from the client's perspective.
+
+1. Resources must not rely on the Transaction Control service recognising duplicate enlistments. A resource
+should be enlisted at most once.
+
+
+ [1]: localJDBC.html
+ [2]: xaJDBC.html
+ [3]: localJPA.html
+ [4]: xaJPA.html
\ No newline at end of file
Modified: aries/site/trunk/content/modules/tx-control/advancedScopes.mdtext
URL: http://svn.apache.org/viewvc/aries/site/trunk/content/modules/tx-control/advancedScopes.mdtext?rev=1743006&r1=1743005&r2=1743006&view=diff
==============================================================================
--- aries/site/trunk/content/modules/tx-control/advancedScopes.mdtext (original)
+++ aries/site/trunk/content/modules/tx-control/advancedScopes.mdtext Mon May 9 17:01:16 2016
@@ -16,4 +16,57 @@ Notice: Licensed to the Apache Softwa
specific language governing permissions and limitations
under the License.
-#TODO
\ No newline at end of file
+#Advanced Scope control
+
+There are a number of useful ways to interact with the scopes created by the Transaction Control Service
+
+## Determining the current scope
+
+The Transaction Control Service has methods which can be used to work out whether a scope is in effect:
+
+* <code>txControl.activeScope();</code> - When <code>true</code> there is a scope in effect and resources can be
+accessed. The scope may, or may not, be transactional. When false there is no current scope and
+<code>txControl.getCurrentContext();</code> will return <code>null</code>.
+
+* <code>txControl.activeTransaction()</code> - When <code>true</code> there is a transactional scope in
+effect and resources can be accessed transactionally. When false there may, or may not, be a "No Transaction"
+scope in effect.
+
+Note that <code>assert txControl.activeTransaction();</code> can be used to enforce the presence of a
+transaction. This is equivalent to a "Mandatory" transaction in Spring or Java EE.
+
+## Avoiding rollback
+
+When setting up a transaction certain exception types can be marked as not triggering rollback:
+
+ txControl.build()
+ .noRollbackFor(MyCustomException.class)
+ .required(() -> {
+ // A MyCustomException thrown here will not trigger rollback
+ });
+
+
+## Nesting a transaction
+
+Nesting a Transaction can easily be managed using <code>requiresNew()</code>
+
+
+ txControl.required(() -> {
+ // Do some work...
+
+ return txControl.requiresNew(() -> {
+ // Do some more work
+ });
+ });
+
+## Suspending a transaction
+
+Suspending a Transaction can easily be managed using <code>notSupported()</code>
+
+ txControl.required(() -> {
+ // Do some work...
+
+ return txControl.notSupported(() -> {
+ // Do some more work
+ });
+ });