Top Banner
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]
33

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

Jan 06, 2017

Download

Technology

mfrancis
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 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]

Page 2: 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

•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

Page 3: 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

Transactions in Software

Page 4: 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

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

Page 5: 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

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

Page 6: 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

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

Page 7: 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

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?

Page 8: 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

How do Declarative Transactions Work?

Page 9: 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

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

Page 10: 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

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!

Page 11: 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

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

Page 12: 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

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?

Page 13: 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

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!

Page 14: 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

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…

Page 15: 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

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!

Page 16: 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

The OSGi Transaction Control Service

Page 17: 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

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.

Page 18: 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

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

Page 19: 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

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

Page 20: 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

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

Page 21: 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

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!

Page 22: 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

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

Page 23: 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

Advanced features of Transaction Control

Page 24: 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

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!

Page 25: 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

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

Page 26: 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

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!

Page 27: 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

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

Page 28: 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

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

Page 29: 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

Playing with Transaction Control

Page 30: 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

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

Page 31: 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

Page 32: 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

• 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

Page 33: 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

www.paremus.com @Paremus [email protected]