Title:
Notice:    Licensed to the Apache Software Foundation (ASF) under one
           or more contributor license agreements.  See the NOTICE file
           distributed with this work for additional information
           regarding copyright ownership.  The ASF licenses this file
           to you 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.

#Getting started with the Transaction Control Service

To make use of scoped resources and transactions using the transaction control service you need two things:

 * A <code>org.osgi.service.transaction.control.TransactionControl</code> implementation 
(found in the service registry). You may want to start with [local transactions][1].

 * A <code>org.osgi.service.transaction.control.ResourceProvider</code> for each of the 
resources that you want to use. You may want to start with [local JDBC][2].


##Scoping Work using TransactionControl

The Transaction Control Service defines three different scopes:

* Unscoped - There is no scope associated with the current thread

* _No Transaction Scope_ - There is a scope associated with the current thread, but no ongoing transaction

* _Transactional Scope_ - There is an ongoing transaction associated with the current thread

Scoped resources have different behaviours in each of these three scopes:

* Unscoped - The resource is generally not usable and will throw exceptions

* _No Transaction_ Scope - The same physical resource will be used throughout the scope, 
and will be automatically tidied up at the end of the scope (e.g. closed or returned to a pool)

* _Transactional Scope_ - The same physical resource will be used throughout the scope, will be 
automatically committed or rolled back up at the end of the transaction, and then tidied up afterwards

###Starting and Finishing scopes

A scope is defined using a piece of work wrapped in a <code>Callable</code>. This means that it is lambda-friendly.

    Integer result = txControl.required(() -> {
            //Work goes in here
            return 42;
        });

The scope starts immediately before the work is executed, and finishes immediately afterwards. The 
<code>required</code> and <code>requiresNew</code> methods can be used to ensure that a 
_Transactional_ scope has been started. The <code>supports</code> and <code>notSupported</code>
methods can be used to ensure that a _No Transaction_ scope has been started.

Simple scope management is perfect in most situations, but you may also wish to read about
[more advanced scope control techniques][3] or [exception management][4] once you've mastered the basics.
There are also some things to consider if you're [migrating from Spring or Java EE][5].

##Accessing Resources

A <code>ResourceProvider</code> is a generic factory for scoped resources. Typically you will use a more 
specific interface for type safety. For example the Transaction Control specification defines 
<code>JDBCConnectionProvider</code> and <code>JPAEntityManagerProvider</code> interfaces. If
needed you can [make your own ResourceProvider][6].

To create your scoped resource you make one call to <code>getResource</code> passing in the 
<code>TransactionControl</code> service that the resource should integrate with. The returned object
is thread-safe, and can be cached for use in any scope.

###Declarative Services Example

The following component provides read and write access using JDBC to a list of messages created by a user. 
The transactionality and lifecycle of the database resources is automatically managed.

    @Component
    public class MyDaoImpl implements MyDao {

        @Reference
        TransactionControl control;

        Connection dbConn;
        
        @Reference
        void setResource(JDBCConnectionProvder provider) {
            dbConn = provider.getResource(control);
        }
        
        @Override
        public void saveMessage(String user, String message) {
            txControl.required(() -> {
                    PreparedStatement ps = connection.prepareStatement(
                            "Insert into MESSAGES values ( ?, ? )");
                    ps.setString(1, user);
                    ps.setString(2, message);
                    return ps.executeUpdate();
                });
        }
        
        @Override
        public void getMessagesForUser(String user) {
            return txControl.supports(() -> {
                    PreparedStatement ps = connection.prepareStatement(
                            "Select MESSAGE FROM MESSAGES WHERE USER = ?");
                    ps.setString(1, user);
                    
                    List<String> result = new ArrayList<>();

                    ResultSet rs = ps.executeQuery();
                    
                    while(rs.next()) {
                        result.add(rs.getString(1));
                    }
                    
                    return result;
                });
        }
    }


  [1]: localTransactions.html
  [2]: localJDBC.html
  [3]: advancedScopes.html
  [4]: exceptionManagement.html
  [5]: spring-tx.html
  [6]: advancedResourceProviders.html