Transaction Control – a Functional Approach to Modular Transaction Management - Tim Ward

33
Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. OSGi Community Event Nov 2016 OSGi Community Event 2016 co-located at EclipseCon Europe 2016 Transaction Control – A functional approach to modular transaction management Tim Ward http://www.paremus.com [email protected]

Transcript of Transaction Control – a Functional Approach to Modular Transaction Management - Tim Ward

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

OSGi Community Event 2016co-located at

EclipseCon Europe 2016

Transaction Control – A functional approach to modular transaction management

Tim Ward http://www.paremus.com [email protected]

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

•Chief Technology Officer at Paremus

• 8 years developing OSGi specifications

•Chair of the OSGi IoT Expert Group

• Interested in Asynchronous Distributed Systems

•Author of Manning’s Enterprise OSGi in Action

• http://www.manning.com/cummins

Who is Tim Ward? @TimothyWard

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Transactions in Software

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Controlling Software Transactions

Software Transactions have existed since the early 1960sThey exist as a means to ensure data integrity

Early transactions used special operating systems and vendor APIsUsually these systems performed offline batch reconciliation

Modern transaction processing systems normally provide real-time updateHandling individual updates leads to the concepts behind ACID

Despite the growth of NoSQL datastores, transactions are still a vital tool

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Controlling Software Transactions (2)

Originally transactions were all imperatively controlledDirect calls to start, stop, and invalidate the transactionYou have to be very careful to handle every return (especially Exceptions)

Managing transactions this way is verbose and error proneThis lead to the development of declarative transactions

Declarative Transactions use metadata to define the transaction boundaryApplication code is freed from boilerplate, and mistakes

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Declarative Transactions in Java

Does anyone remember EJB 1/2?Despite the horror of its XML, transactions were simpler than before

The Spring framework added AOP driven transaction management and later annotation driven transaction configuration

EJB 3 adopted many of the principals provided by SpringCDI takes this even further

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Problems with Declarative Transactions

It may seem that we’ve reached the perfect solutionHow can this get any simpler?@Transactionalpublic void doUpdate(String foo) {

…}

Annotations are seductively simple butWe’ve traded visible complexity for invisible complexity

It’s better that we aren’t directly driving the transactionsBut who is driving, and can we rely on them?

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

How do Declarative Transactions Work?

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Aspect Oriented Programming

Obviously Declarative Transactions must still be started somehowSome container code must run to manage the transaction lifecycle

Typically transactions are run as intercepting “aspects”These run before and after every intercepted method call

Aspects like this run in one of two ways:The container “weaves” extra bytecode instructions into your classThe container creates a delegating proxy, which wrappers your class

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Aspect Oriented Programming (2)

The two different implementations have different advantages and drawbacks

Proxying works best when you can proxy by interfaceFinal classes, final methods and private methods cannot be proxiedCasting to instance types does not workObject identity may be affected

Weaving avoids these drawbacks, but…It either needs a pre-deployment step, or a custom class loader It messes up the Java debugger (there’s a lot of code at line 0)It provides inconsistent behaviour compared to proxying!

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Enlisting Resources

Starting a Transaction is only one part of the problem

In order to participate in a Transaction a resource must “enlist” in itThis applies to any Database or JMS Connections, and all other resources

All of this happens transparently to the code using the resourceBut only if the right resource is used!

This is why you must use JNDI to get resources in your App ServerEven Spring requires you to set up Transactional resources

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

The Proxying problem

Proxying is usually the preferred solution as it is less invasiveBut we mentioned that it is inconsistent compared to weaving…

Consider the following object methods:@Transactional(SUPPORTS)public void doCheckAndUpdate(String foo) {

// Do some non-transactional work…// Do an updatedoUpdate(foo);

}

@Transactional(REQUIRED)public void doUpdate(String foo) {

// There must be a transaction here!…

}

Does this requirement hold?

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

The Proxying problem (2)

Aspects provided by proxies can only run when the proxy is calledIn our method the proxy is not called!@Transactional(SUPPORTS)public void doCheckAndUpdate(String foo) {

// Do some non-transactional work…// Do an updatedoUpdate(foo);

}

As a result the doUpdate method may not always run in a transactionSwitching to weaving will make sure the right boundary is in placeBut your application should not need to care about this!

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Rolling back on failure

A vital behaviour for Transactions is rolling back when things go wrongThe most obvious reason for rollback is if the method throws an Exception

Java EE decided to do something very strange (copied by Spring)Unchecked Exceptions trigger rollbackChecked Exceptions do not trigger rollback

The rationale for this is that a checked Exception is part of the APIThis is a horrible thing to do to your users!Exceptions should never be used as control flowAlso SQLException is a checked Exception…

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

So what can we do?

The use of declarative transactions is not 100% positiveYes our code is simpler, but it’s still not always correctWe have traded visible complexity for invisible complexity!

In a modular system we must do betterWe need to express dependencies on the features we needWe need to be able to rely on consistent behaviours using contractsWe need to be able to cope when no central container exists

Also - let’s fix the crazy transaction behaviour!

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

The OSGi Transaction Control Service

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

The basics of OSGi Transaction Control

The OSGi Transaction Control service has two main goalsSimple, explicit management of transactional workModular support for resources with managed lifecycles

What does this mean in practice?You tell Transaction Control what transaction scope you wantYou tell your resources which Transaction Control service to use

From there all the transaction and resource lifecycle is handled for you.

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Using Transaction Control to scope work

Transaction Control uses a functional API Your business logic is passed as a function to be run within a “scope”A scope can be transactional, or non-transactional

Transaction control provides four well-known options for scoping your workrequired - ensures that a transactional scope is runningrequiresNew - begins a new transactional scopesupports - ensures that a scope (with or without a transaction) is runningnotSupported - ensures that a non-transactional scope is running

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Using Transaction Control to scope work (2)

It should be obvious that a scope is more than just a transaction

A scope provides a context for your workA place to store stateA place to register completion callbacksAn access boundary for your resources

Scopes provide a safe way to access resources without leaksThe resource is lazily retrieved the first time you use it in a scopeThe same resource is the available throughout the scopeThe resource is automatically released when the scope ends

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Finishing Scopes

A scope ends once the work function has returnedResource clean up happens regardless of whether the work is successfulThe value returned by the work is returned by the scope

Transactional work has additional rules for the transaction lifecycle:If the scope has been marked for rollback it always rolls backIf the work exits with an Exception then the transaction rolls backIf the work exits with a normal return then the transaction commits

Specific Exception types can be marked not to cause rollback

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Scoped Resources

Transaction Control works best when used with scoped resources

A Scoped Resource is created from a ResourceProviderResourceProvider#getResource(TransactionControl)

Typically a more specialised sub-interface provides type-safetyJDBCConnectionProvider -> java.sql.ConnectionJPAEntityManagerProvider -> javax.persistence.EntityManager

The returned object is a thread-safe proxyJust use it in your methods whenever you need it!

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Putting it all together

@Componentpublic class TxComponent {

@Reference TransactionControl txControl;

@Reference JPAEntityManagerProvider jpa;

EntityManager em;

@Activate void start() { em = jpa.getResource(txControl); }

public void doUpdate(MyEntity foo) { txControl.required(() -> { em.persist(foo); return null; }); }}

Inject the services

Create the scoped resource

Use the scoped resource, safe in the knowledge that it will be committed and cleaned up

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Advanced features of Transaction Control

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

XA or Resource-Local transactions?

Most resource types have a programatic API for commit/rollbackThese only apply to a single resource and so are “Resource Local”

If multiple resources are used in the same transaction then we need moreThe XA protocol defines a robust distributed state machine

Transaction Control supports lightweight resource-local transactionsThe osgi.xa.enabled property can be used to select an XA implementation

Importantly the client API is the same whichever you use!

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Connection Pooling

Connection Pooling in OSGi can be challenging…Most pooling implementations try to directly load the driverThe client often ends up coupled to the pooling implementation

The Resource Provider offers an excellent solution

The JDBCConnectionProvider has built-in support for connection poolingFully configurable using a standard factory serviceProviders can also be defined using Configuration Admin

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

No Rollback for…

When starting a transaction the user can nominate Exception typesThese types can explicitly trigger, or not trigger, rollback.

txControl.build() .noRollbackFor(SocketException.class, RemoteException.class) .rollbackFor(ConnectException.class) .required(() -> { em.persist(foo); return null; });

Be careful when using these!

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Nested Scopes

Transaction Control Scopes can be easily nestedCommitting a quick status update part way through a batchQuerying for sequence numbers outside the current transaction

Each scope is isolated using separate resource instancesThe scopes also have separate contexts and lifecycle callbacks

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Introspecting the Scope

The Transaction Control service can be used to query the current scopeWhat type of scope is it?Querying for sequence numbers outside the current transaction

Each scope is isolated using separate resource instancesThe scopes also have separate contexts and lifecycle callbacks

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Playing with Transaction Control

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Playing with Transaction Control

Let’s use Transaction Control to build a simple REST microserviceJAX-RS for request mappingJPA persistence into a database

A simple HTML/JavaScript UI running in the browser

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

• For more about OSGi...• Specifications at http://www.osgi.org

• Enterprise OSGi in Action

• http://www.manning.com/cummins

• For more about Transaction Control• http://github.com/osgi/design

• http://aries.apache.org/modules/transactioncontrol.html

Questions?

Thanks!

http://www.paremus.com [email protected]

http://www.manning.com/cummins

Copyright © 2005 - 2016 Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved.

OSGi Community Event Nov 2016

www.paremus.com @Paremus [email protected]