---
title: "Servicio de Transacciones distribuidas ¿Cómo usarlo  en Plataforma?"
canonical: "https://onesaitplatform-es.refined.site/space/DOC/229801985/Servicio%20de%20Transacciones%20distribuidas%20%C2%BFC%C3%B3mo%20usarlo%20%20en%20Plataforma%3F"
format: markdown
---
> Macro (toc)

> ℹ️ Esta funcionalidad está disponible a partir de la versión 1.6.0.

## Introducción

Definimos el concepto de transacción como un conjunto de operaciones sobre una base de datos que se deben ejecutar como una unidad, ya que hay ocasiones en las que es necesario que varias operaciones sobre una base de datos se realicen en bloque, es decir, que se ejecuten o todas o ninguna, pero no que se realicen unas sí y otras no.

Por lo que el soporte transaccional permite a las aplicaciones asegurarse de que:

- Se ejecutan todas las operaciones a realizar.
- Cuando falla una de las operaciones de una transacción, todas las demás operaciones realizadas hasta el momento se revierten.

## Integración con el Digital Broker 

Se han añadido tres operaciones nuevas:

> ℹ️ En todas ellas es necesario añadir en la petición la cabecera “Authorization” con la sessionKey obtenida anteriormente con el método “Join”.

- **Start**: Operación GET que inicia una transacción. Como resultado de esta operación, obtendrás el **transactionId** que te servirá como identificador único de la transacción.

![image](media://48164f11-db83-4509-ad8e-a0b66505736d)

- **Commit**: operación GET que realiza el commit de la transacción, es decir, ejecuta todas las operaciones asignadas a la transacción. En este caso es necesario pasarle el transactionId, de la transacción que se quiere ejecutar, y el parámetro **lockOntologies,** que te permite decidir si quieres bloquear las ontologías afectadas en la transacción.

![image](media://dc9ee1eb-264e-4ec1-bc05-0da204f5d861)

- **Rollback**: Borra una transacción y revierte todas las operaciones ya ejecutadas de la misma. Este servicio recibe como argumento el transactionId.

![image](media://cf0586d9-77b2-40e0-962b-3557773dd27a)

Además se han extendido todos los métodos INSERT, UPDATE, DELETE para que admitan una nueva cabecera opcional **TransactionId**, de tal forma que si se añade esta cabecera, la operación se añadirá a la transacción, mientras que, si se omite, se realizará la operación de forma normal.

![image](media://53d83b36-cf68-42f3-af63-d4aa84fd93ac)

## Integración con el Cliente Java

> ℹ️ Por ahora sólo están soportadas las transacciones para operaciones REST. En el futuro se soportarán también protocolo MQTT. Se recomienda la lectura del tutorial[https://onesaitplatform.atlassian.net/wiki/spaces/OP/pages/975306753](https://onesaitplatform.atlassian.net/wiki/spaces/OP/pages/975306753)para entender cómo funciona esta librería y cómo hay que configurarla.

Se ha extendido la librería del cliente Java para soportar las transacciones sobre plataforma. 

Para ello se ha creado una clase **Transaction**. Esta clase cuenta con los métodos INSERT, UPDATE y DELETE y además añade los métodos siguientes:

- **ConfigureConnection**: es el encargado de abrir la conexión con la plataforma y recibe como parámetros de entrada:
  - ConnectionType: se trata de un Enum que puede ser REST o MQTT (Recuerda que por ahora sólo se soporta REST).
  - Properties: objeto que almacena los parámetros necesarios para establecer la conexión. Para hacerlo lo más estándar posible. se ha definido además una clase Enum RestProperty con el listado de los posibles parámetros necesarios para estables dicha conexión.
- **Start**: crea una nueva transacción y recibe como parámetros de entrada:
  - Device: nombre del Device definido en plataforma.
  - Token: un token cálido asociado al Device definido a plataforma.
  - DeviceTemplate: identificador elegido por el usuario para identificar la conexión.
- **Commit**: realiza las operaciones asociadas a una transacción y recibe como parámetro de entrada:
  - **LockOntologies**: boolean que indica si se quiere que las ontologías se bloqueen o no.

A continuación se muestra un ejemplo práctico de uso:

> ℹ️ Hay que usar al menos la versión 1.3.8 de la librería.


```java
public static void main(String[] args) throws SSAPConnectionException {
  final String token = "e7ef0742d09d4de5a3687f0cfdf7f626";
  final String deviceTemplate = "TicketingApp";
  final String device = "TicketMachine1";
  final String ontology = "Ticket";
  final ObjectMapper mapper = new ObjectMapper();
  Properties prop = new Properties();
  prop.put(Transaction.CONNECTION_TYPE, Transaction.ConnectionType.REST.name());
  prop.put(Transaction.DIGITAL_BROKER_REST_ENDPOINT, "http://localhost:19000/iot-broker");
  Transaction tx = new Transaction();
  tx.configureConnection(prop);
  try { 
		log.info("Example with transaction:");
  
		log.info("1. Starting transaction.");
		String transactionId = tx.start(token, deviceTemplate, device);
		log.info("...Started transaction. Transaction id: {}", transactionId);
  
		String instance = "{\"Ticket\":{\"identification\":\"WithoutTransaction\",\"status\":\"DONE\",\"email\":\"iex@email.com\",\"name\":\"Alberto\",\"response_via\":\"email\",\"file\":{\"data\":\"\",\"media\":{\"name\":\"\",\"storageArea\":\"SERIALIZED\",\"binaryEncoding\":\"Base64\",\"mime\":\"application/pdf\"}},\"coordinates\":{\"coordinates\":{\"latitude\":45.456,\"longitude\":-41.283},\"type\":\"Point\"}}}";
		log.info("2. Inserting one instance with transaction id {}: {}", transactionId, instance);
		String idInsertTx = tx.insert(ontology, mapper.readTree(instance).toString());
		log.info("...Inserted instance in transaction {} with id {}", transactionId, idInsertTx);
  
		instance = "{\"Ticket\":{\"identification\":\"ticket_updated\",\"status\":\"DONE\",\"email\":\"iex@email.com\",\"name\":\"Alberto\",\"response_via\":\"email\",\"file\":{\"data\":\"\",\"media\":{\"name\":\"\",\"storageArea\":\"SERIALIZED\",\"binaryEncoding\":\"Base64\",\"mime\":\"application/pdf\"}},\"coordinates\":{\"coordinates\":{\"latitude\":45.456,\"longitude\":-41.283},\"type\":\"Point\"}}}";
		log.info("3. Inserting one instance with transaction id {}: {}", transactionId, instance);
		idInsertTx = tx.insert(ontology, mapper.readTree(instance).toString());
		log.info("...Inserted instance in transaction {} with id {}", transactionId, idInsertTx);
  
		log.info("4. Commit transaction with transaction id {}", transactionId);
		tx.commit(true);
		log.info("..Transaction commited with id {}", transactionId);
  
		log.info("Example with transaction OK!!!");
  
  } catch (final Exception e) {
		log.error("Error in process", e);
		tx.rollback();
  }
}
```

Es importante fijarse en algunos detalles:

1. *(Línea 8) *Añadimos al objeto *Properties* el parámetro *CONNECTION_TYPE*. En este caso vamos a realizar la conexión vía REST por lo que vamos a tener que añadir también el parámetro *DIGITAL_BROKER_REST_ENDPOINT.*
2. *(Línea 11) *Se abre la conexión con la plataforma.
3. *(Línea 16)* Aquí se crea la transacción. El método *start* nos devuelve el *transactionId* pero este parámetro es meramente informativo, ya que la librería internamente se ocupa de gestionar la transacción. Es decir, todas las operaciones asignadas al mismo objeto *Transaction* van a pertenecer a la misma transacción.
4. *(Líneas 21 y 26)* Se añaden dos operaciones *insert* a la transacción.
5. *(Línea 30)* Se realiza el *commit *de la transacción.
6. *(Línea 37)* En el caso de cualquiera de las operaciones lance una excepción se lanza la operación *rollback*.

## Integración con el Cliente IoTClient4SpringBoot

> ℹ️ Se recomienda la lectura del tutorial [https://onesaitplatform.atlassian.net/wiki/spaces/DOC/pages/2215909434](https://onesaitplatform.atlassian.net/wiki/spaces/DOC/pages/2215909434) para una total comprensión de dicha librería.

Se ha extendido también la librería **IoTClient4SpringBoot** para soportar las operaciones dentro de una transacción.

Para ello se ha creado una nueva etiqueta** *****@IoTBrokerTransaction***** **que se asignará a nivel de método, de tal forma que cuando se ejecute un método marcado con esta etiqueta se seguirá el siguiente flujo:

1. Nada mas entrar al método y antes de realizar ninguna operación del mismo, se abrirá una transacción nueva.
2. Todas las operaciones INSERT, UPDATE y DELETE que se definan dentro de dicho método irán asignadas a la transacción.
3. Al salir del método:
  1. Si todo ha ido bien, se realiza el *commit *de la transacción.
  2. Si se lanza alguna excepción, se realiza *rollback* de todas las operaciones y se elimina la transacción.

> ℹ️ En el caso de que en el mismo flujo de la aplicación se encuentre más de una etiqueta IoTBrokerTransaction, se tomará cómo válida la primera del primer método, siendo ignoradas las etiquetas posteriores.

A continuación se muestra un ejemplo práctico de cómo utilizar esta funcionalidad:

> ℹ️ Hay que usar al menos la versión 1.3.8 de la librería.


```java
	@IoTBrokerTransaction(lockOntologies = true)
	public void insertInstances() throws Exception {

		log.info("Ticket is going to be inserted.");
		CitizenTicket ticket = new CitizenTicket();
		ticket.setEmail("onesaitplatform@indra.es");
		ticket.setStatus("PENDING");
		ticket.setName("Onesait Platform");
		ticket.setIdentification("Ticket creado desde el check...");
		CitizenTicketOntology ticketOnt = new CitizenTicketOntology();
		ticketOnt.setCitizenTicket(ticket);

		String result = ticketRepository.insertTicket(ticketOnt);
		log.info("Result insert 1: {}", result);
	}
```

Cabe destacar:

1. *(Línea 1)* se añade la etiqueta *@IoTBrokerTransaction *y se le añade el parámetro *lockOntologies = true*. Este parámetro es utilizado a la hora de hacer el *commit *de la transacción e indica si las ontologías van a ser bloqueadas durante la transacción o no. Si no se indica este parámetro, se tomará como valor por defecto *false*.
2. *(Línea 13)* A la hora de realizar una inserción, se realiza de la misma forma que se han realizado los inserts fuera de las transacciones. Internamente, la librería se encarga de añadir esta operación a la transacción por encontrarse dentro de un método con la etiqueta *@IoTBrokerTransaction*.