Blog

Support For Transaction API For Codeless

by on June 25, 2021

Transaction API for Codeless

In 2020, we released the Transaction API as one of our built-in API services. The purpose of transactions is to protect your data from partial database updates that fail to complete. The Transaction API is now available for Codeless.

We defined the Transaction API in our release article last year:

With the Transaction API, Backendless Database can execute multiple database requests grouped into a single transaction. When any one of these grouped database operations fails, the entire transaction is rolled back – meaning any other changes within the same transaction are canceled.

Until now, the Transaction API was limited to Backendless users building with code. Now, the API is available for Codeless developers as well.

Click here to view the complete Codeless Transaction API documentation.

The following section describes how the Transaction API works and some of its many benefits.

To jump to our Codeless example, click here.

Benefits Of Transactions

So, what does the transaction API do for you? Let’s look at some of the benefits.

First, if any of the operations fail, the entire transaction is rolled back – there is no need to perform any clean up from your code. In other words, no permanent changes are made to your database that would need to be fixed if an operation fails.

Next, from the client-side perspective, there is only one request going to the server – the request to execute the transaction. For instance, say a transaction performs two operations: (1) saving an object in the database and (2) establishing a relationship between the saved object and others identified with a query. With the Transaction API, the client application sends only one request to the server.

Third, transactions provide consistency and referential integrity for your database. In other words, transactions ensure that there is no “dirty data” in your database. This helps keep your client-side code cleaner and the data consistent.

How the Transactions API Works

Backendless transactions rely on the following concepts:

  • Unit of Work – is the entire payload of the transaction request which combines multiple individual database operations into a single object. All operations added to a unit of work have a sequence number and will be executed on the server-side in the same order they were added. A unit of work essentially represents a transaction; for more information, see the Unit of Work section of the documentation.
  • Database Operation – a single operation executed within a transaction. This can be either a create, retrieve, update, delete and relation management (create, update, delete) operation;
    Create object in database with Backendless Codeless Transaction API
  • Operation Result – an entity representing the result of an individual database operation. The result of one operation can be referenced in other subsequent operations.
    Get operation result with Backendless Codeless Transaction API
    For example, a “create” operation returns a result. The result represents the object saved in the database. That object may be referenced in an operation to set a relationship for the object. Alternatively, you can “extract” the value of a specific property from the operation result and also use it in other operations in the same transaction.

The diagram below illustrates these concepts as they relate to each other:

Unit of Work API

The heart of the Backendless Transactions API is a request called UnitOfWork. It is used by client applications to compose a transaction.

Find operation for Backendless Codeless Transaction API

Composing a transaction means adding various database operations to a unit of work. The “Find” operation, for retrieve objects from your database, is shown above.

These operations may be “linked” to each other by using the output/result on one operation as the input for another. For example, in the block below, we see an example of an “Update” operation with the option to refer to a previous operation in the transaction.

Update operation for Backendless Codeless Transaction API

When the server receives a UnitOfWork request, it starts processing its operations. The server executes all operations one-by-one in the context of a single database transaction.

If any of the operations fails, Backendless rolls back all the changes and returns the information about the result of each operation to the client. However, if all operations succeed, the entire database transaction is committed. This means the data will be finalized in the database.

Transaction Isolation

Using Backendless Transaction API, you can configure an isolation level for your transaction. The isolation level determines how the Backendless database separates your transaction from all others running at the same time.

Create transaction Codeless block for Backendless Transaction API

Without any isolation, one transaction could modify the data another transaction is reading and, by doing so, data inconsistency would be created.

Isolation levels determine how isolated your transaction is from others. This is implemented by applying a lock on the data retrieved in a transaction.

Different levels of isolation imply different locking mechanisms, each of which also yield various data read phenomena (described further in the documentation). Backendless supports four isolation levels.

Operation Result

One of the most powerful elements of the Transaction API is the ability to use the result of an operation in other subsequent operation(s) within the same transaction. This is made possible by a “protocol” that all transactional operations follow: every operation can have a unique identifier.

The identifier can be used in another operation to reference the result from the operation where it was used. This allows for a “chaining effect” where data comes out of one operation and is then fed into another.

Consider the example below. The example saves a new object in the database and then establishes a relationship between the created object and objects in another table.

The operation to save the object in the database assigns a unique ID to each operation. This ID is then used in the subsequent operation to establish a relationship between the object and its children.

Codeless Transaction Example

We are going to walk through the following Codeless transaction to break down what is happening in each step. This Codeless block is being used to store details of a purchase. Below, we walk through each step of this API call.

Codeless Transaction API Example

For reference, the table schemas for the two tables in this example are found below. Here’s a breakdown of each step of this API service:

  1. First, for this example, we are going to create an API Service called TransactionsDemo with the Method name createObjectsSaveRelation. You do not have to create a new API Service to run the logic in this example; all of the following steps can be used in most any Codeless logic you create.
  2. Next, we create a variable myTx and set its contents to be a new transaction. The isolation for the transaction is set to “Repeatable read”. You can read more about the different transaction isolation levels here.
  3. This is the “wrapper” for your transaction. Here, we implement the operations that make up the transaction (or UnitOfWork) named myTxNote: Keep in mind, order matters. Particularly if you have operations that are dependent on another operation in the same transaction, you will need to be sure you put your operation steps in the right order to achieve your desired result.
  4. As the first operation in our transaction, we perform a “Create” operation named createOrderOp. This operation creates an object with orderId = 061821-CV1 and amount = 189.2 in the Order table.
  5. For the second operation, we perform a “Bulk Create” operation and name it createOderItemsOp. In this operation, we create two data objects – Paper Towels with quantity = 10 and Bathroom Tissue with quantity = 20. These items are added to the table OrderItem.
  6. Finally, we perform a “Set Relation” operation to connect our children data objects to our parent. We don’t need to give this operation a name (id). For the parent, we are accessing the Order table. The parent object is then found by accessing the result of the createOrderOp operation. The column we are creating a relation to is called orderDetails. To find the children options, we will again access the result of a previous operation. This time, it’s the createOrderItemsOp operation.

Transaction Result

The result of this API call will be:

{
  "success": true,
  "error": null,
  "results": {
    "set_relationOrder1": {
      "result": 2,
      "operationType": "SET_RELATION"
    },
    "createOrderItemsOp": {
      "result": [
        "43925FB1-1F7A-41E6-B8C5-0FB5F8566FE3",
        "91026D1C-217E-4078-AEDD-2DBDBD10BF7E"
      ],
      "operationType": "CREATE_BULK"
    },
    "createOrderOp": {
      "result": {
        "amount": 189.2,
        "orderId": "061821-CV1",
        "created": 1624004146000,
        "___class": "Order",
        "ownerId": null,
        "updated": null,
        "objectId": "3A04D2B6-44D3-4A08-AC56-A316366C5069"
      },
      "operationType": "CREATE"
    }
  }
}

Codeless Example Table Schemas

Order table schema:

OrderItem table schema:


Support for transactions in Codeless is just one of the powerful new features in this release. You can read our articles about the other new features released below:

  1. OAuth 2.0 Integration
  2. Support For Multiple Custom Domains Per App
  3. Deep Save API

Thanks for reading and Happy Codeless Coding!

Leave a Reply