anchor.diff:  include::./attributes.adoc[]
   :extension-status: preview
   
  -Quarkus supports the Software Transactional Memory (STM) implementation provided by the
  -Narayana open source project. Narayana STM allows a program to group object accesses into
  -a transaction such that other transactions either see all of the changes at once or they
  -see none of them.
  -
  -STM offers an approach to developing transactional applications in a highly concurrent
  -environment with some of the same characteristics of ACID (Atomicity, Consistency,
  -Isolation and Durability) transactions.
  -
  -To use Narayana STM you must define which objects you would like to be transactional using java
  -annotations. Please refer to the https://narayana.io/docs/project/index.html#d0e16066[Narayana STM manual]
  -and the https://narayana.io//docs/project/index.html#d0e16133[STM annotations guide] for more details.
  +Software Transactional Memory (STM) has been around in research environments since the late
  +1990's and has relatively recently started to appear in products and various programming
  +languages. We won't go into all of the details behind STM but the interested reader could look at https://groups.csail.mit.edu/tds/papers/Shavit/ShavitTouitou-podc95.pdf[this paper].
  +However, suffice it to say that STM offers an approach to developing transactional applications in a highly
  +concurrent environment with some of the same characteristics of ACID transactions, which you've probably already used
  +through JTA. Importantly though, the Durability property is relaxed (removed) within STM implementations,
  +or at least made optional. This is not the situation with JTA, where state changes are made durable
  +to a relational database which supports https://pubs.opengroup.org/onlinepubs/009680699/toc.pdf[the X/Open XA
  +standard].
  +
  +Note, the STM implementation provided by Quarkus is based on the https://narayana.io/docs/project/index.html#d0e16066[Narayana STM] implementation. This document isn't meant to be a replacement for that project's documentation so you may want
  +to look at that for more detail. However, we will try to focus more on how you can combine some of the key capabilities
  +into Quarkus when developing Kubernetes native applications and microservices.
  +
  +== Why use STM with Quarkus?
  +
  +Now you may still be asking yourself "Why STM instead of JTA?" or "What are the benefits
  +to STM that I don't get from JTA?" Let's try to answer those or similar questions, with
  +a particular focus on why we think they're great for Quarkus, microservices and Kubernetes
  +native applications. So in no specific order ...
  +
  +* The goal of STM is to simplify object reads and writes from multiple threads/protect
  +state from concurrent updates. The Quarkus STM implementation will safely manage any conflicts between
  +these threads using whatever isolation model has been chosen to protect that specific state
  +instance (object in the case of Quarkus). In Quarkus STM, there are two isolation implementations,
  +pessimistic (the default), which would cause conflicting threads to be blocked until the original
  +has completed its updates (committed or aborted the transaction); then there's the optimistic
  +approach which allows all of the threads to proceed and checks for conflicts at commit time, where
  +one or more of the threads may be forced to abort if there have been conflicting updates.
  +
  +* STM objects have state but it doesn't need to be persistent (durable). In fact the
  +default behaviour is for objects managed within transactional memory to be volatile, such that
  +if the service or microservice within which they are being used crashes or is spawned elsewhere, e.g.,
  +by a scheduler, all state in memory is lost and the objects start from scratch. But surely you get this and more
  +with JTA (and a suitable transactional datastore) and don't need to worry about restarting your application?
  +Not quite. There's a trade-off here: we're doing away
  +with persistent state and the overhead of reading from and then writing (and sync-ing) to the datastore during each
  +transaction. This makes updates to (volatile) state very fast but you still get the benefits of atomic updates
  +across multiple STM objects (e.g., objects your team wrote then calling objects you inherited from another team and requiring
  +them to make all-or-nothing updates), as well as consistency
  +and isolation in the presence of concurrent threads/users (common in distributed microservices architectures).
  +Furthermore, not all stateful applications need to be durable - even when JTA transactions are used, it tends to be the
  +exception and not the rule. And as you'll see later, because applications can optionally start and control transactions, it's possible to build microservices which can undo state changes and try alternative paths.
  +
  +* Another benefit of STM is composability and modularity. You can write concurrent Quarkus objects/services that
  +can be easily composed with any other services built using STM, without exposing the details of how the objects/services
  +are implemented. As we discussed earlier, this ability to compose objects you wrote with those other teams may have
  +written weeks, months or years earlier, and have A, C and I properties can be hugely beneficial. Furthermore, some
  +STM implementations, including the one Quarkus uses, support nested transactions and these allow changes made within
  +the context of a nested (sub) transaction to later be rolled back by the parent transaction.
  +
  +* Although the default for STM object state is volatile, it is possible to configure the STM implementation
  +such that an object's state is durable. Although it's possible to configure Narayana such that different
  +backend datastores can be used, including relational databases, the default is the local operating system
  +file system, which means you don't need to configure anything else with Quarkus such as a database.
  +
  +* Many STM implementations allow "plain old language objects" to be made STM-aware with little or no changes to
  +the application code. You can build, test and deploy applications without wanting them to be STM-aware and
  +then later add those capabilities if they become necessary and without much development overhead at all.
  +
  +== Building STM applications
   
   There is also a fully worked example in the quickstarts which you may access by cloning the
   Git repository: `git clone {quickstarts-clone-url}`, or by downloading an {quickstarts-archive-url}[archive].
  -Look for the `software-transactional-memory-quickstart` example.
  +Look for the `software-transactional-memory-quickstart` example. This will help to understand how you
  +can build STM-aware applications with Quarkus. However, before we do so there are a few basic concepts
  +which we need to cover.
  +
  +Note, as you will see, STM in Quarkus relies on a number of annotations to define behaviours. The lack
  +of these annotations causes sensible defaults to be assumed but it is important for the developer to
  +understand what these may be. Please refer to the https://narayana.io/docs/project/index.html#d0e16066[Narayana STM manual]
  +and the https://narayana.io//docs/project/index.html#d0e16133[STM annotations guide] for more details on
  +all of the annotations Narayana STM provides.
   
   include::./status-include.adoc[]
   
  
positive.code: }
  --
  
  Unless specified using other annotations, all public methods of implementations of this object will be assumed to modify the state of the object.
  Please refer to the Narayana guide for details of how to exert finer grained control over the transactional behaviour of objects that implement
  interfaces marked with the `@Transactional` annotation.
  
  == Creating STM objects
  
  The STM library needs to be told which objects it should be managing by providing a container for the transactional memory.
  The default container (`org.jboss.stm.Container`) provides support for volatile objects that cannot be shared between JVMs
  (although other constructors do allow for other models):
  
  [source,java]
  --
  
negative.code: 
  <1> You need to tell each Container about the type of objects for which it will be responsible. In this example
      it will be instances that implement the FlightService interface.
  <2> Then you create an instance that implements `FlightService`. You should not use it directly at this stage because
      access to it is not being managed by the STM subsystem.
  <3> To obtain a managed instance, pass the original object to the STM `container` which then returns a reference
      through which you will be able perform transactional operations. This reference can be used safely from multiple threads.
  
  == Defining transaction boundaries
  
  Once an object is placed within an STM container the application developer can manage the scope of transactions
  within which it is used. There are some annotations which can be applied to the STM-aware class to have the
  container automatically create a transaction whenever a specific method is invoked.
  
  === Declarative approach
  
  If the `@NestedTopLevel` or `@Nested` annotation is placed on a method signature then the STM container will
  start a new transaction when that method is invoked and attempt to commit it when the method returns. If there is
  a transaction already associated with the calling thread then each of these annotations behaves slightly differently:
  the former annotation will always create a new top-level transaction within which the method will execute, so the enclosing
  transaction does not behave as a parent, i.e., the nested top-level transaction will commit or abort independently; the
  latter annotation will create a transaction with is properly nested within the calling transaction, i.e., that
  transaction acts as the parent of this newly created transaction.
  
  === Programmatic approach
  
  The application can programmatically start a transaction before accessing the methods of STM objects:
  
  [source,java]
  --
  