TCL(transaction Control Language) : TCL commands deals with the transaction within the database.

When running a script, a transaction is automatically opened at the beginning. When script is finished, if an opened transaction is still present, this transaction is commited automaticaly. Inside the script, you can commit this transaction, and then all transaction management is on you.

If you close transactions, then autocommit is applied on each database statement.

1 Automatic commit on finish

Before starting a JavaScript program, a transaction is opened by Axional script engine. When ending Js program, if the transaction is still present the engine commits it automatically or executes a rollback work if ending by exception.

To see how it works, let's create first a sample table.

Copy
CREATE TABLE IF NOT EXISTS test_work(a SMALLINT NOT NULL);

Now, we will insert a row sucessfully. Transacion will be commit after script finishes.

Copy
<script>
    Ax.db.execute("INSERT INTO test_work VALUES(1)");
    // Transaction is still not commited
    console.log(Ax.db.executeQuery("SELECT * FROM test_work"));
    // Transaction will be commited on exit
</script>
+------+
|a     |
+------+
|     1|
+------+

2 Transaction rollback

If the script exists because exception is throwed, then an automatic rollback of current transaction is applied. If you close the transaction, even by rollback or commit instructions, you should take care of reopening a new transaction if required.

In next example, we create a table and execute rollback of transaction, so this table is not really created and a new transaction is opened, then we create the table again and insert a row. Next, we try to insert an invalid data and it produces an exception and script exists. As exit is done by exception, current (last) transaction is rolled back automatically. At the end of script the only transaction applied is the first one with "drop if exists" statement.

Copy
<script>
    // Transaction succeed
    Ax.db.execute("DROP TABLE IF EXISTS test_work");
    Ax.db.commitWork();
    Ax.db.beginWork();

    Ax.db.execute("CREATE TABLE test_work(a SMALLINT NOT NULL)");
    // Current transaction rolled back and a new transaction is created.
    Ax.db.rollbackWork();
    Ax.db.beginWork();

    Ax.db.execute("CREATE TABLE test_work(a SMALLINT NOT NULL)");
    Ax.db.execute("INSERT INTO test_work VALUES(1)");
    console.log(Ax.db.executeQuery("SELECT * FROM test_work"));

    // Transaction fails and exception ocurrs
    Ax.db.execute("INSERT INTO test_work VALUES(NULL)");
    // Rollback is done as script ends with exception

</script>

Rows are not present in table, as previous script has failed and last transaction is rolled back.

Copy
<script>
    console.log(Ax.db.executeQuery("SELECT * FROM test_work"));
</script>
java.sql.SQLException: java.lang.RuntimeException: java.sql.SQLException: The specified table (test_work) is not in the database.

3 Programatic control

Only one transaction can be created at a time. When executing a script, a new transaction is opened automaticaly and when script ends, current transactions is commited if ending properly or rolled back if ending by exception.

You can also manipulate transactions by using transaction functions:

Method Description
Ax.db.beginWork() If a transaction is already openned, this command closes previous transaction executing a "commit work" and opens a new database transaction.
Ax.db.commitWork() Commits current transaction.
Ax.db.rollbackWork() Roll back current transaction.
Ax.db.isOnTransaction() Return true if an open transaction exists.

Next example show you how to use transaction manipulation methods:

Copy
<script>
    Ax.db.execute("CREATE TABLE IF NOT EXISTS test_work(a SMALLINT NOT NULL)");
    Ax.db.execute("DELETE FROM test_work");
    Ax.db.execute("INSERT INTO test_work VALUES(1)");
    Ax.db.execute("INSERT INTO test_work VALUES(2)");
    // commit now
    Ax.db.commitWork();
    Ax.db.beginWork();
    Ax.db.execute("INSERT INTO test_work VALUES(3)");
    // rollback it now
    if (Ax.db.isOnTransaction()) {
        Ax.db.rollbackWork();
    }
    console.log(Ax.db.executeQuery("SELECT * FROM test_work"));
</script>
+------+
|a     |
+------+
|     1|
|     2|
+------+

4 Holdable resultsets

The holdable result set feature permits an application to keep result sets open after implicit or explicit commits.

Copy
<script>
    var rs = Ax.db.executeQuery(`SELECT FIRST 10 tabid, tabname FROM systables`);

    if (Ax.db.isOnTransaction()) {
        Ax.db.commitWork();
    }
    // Ensure transactions don't close ResultSet
    for (var row of rs) {
        Ax.db.beginWork();
        console.log(row.tabid);
        Ax.db.commitWork();
    }
</script>

The resultset cursor returned by Ax.db.executeQuery is held open after a commit. The resultset cursor returned by Ax.db.execute(String sql).getResultSet() is not holdable and closed automatically after a transaction commit.

Copy
<script>
    if (Ax.db.isOnTransaction()) {
        Ax.db.commitWork();
    }
    var rs = Ax.db.execute("SELECT FIRST 10 * FROM systables").getResultSet();
    for (var tab of rs) {
        Ax.db.beginWork();
        console.log("tablename = " + tab.tabname);
        Ax.db.commitWork();
    }
</script>
00:00:00.022:  [1] 1 non holdable prepared statement(s) closed due to begin
tablename = systables

java.sql.SQLException: ResultSet JDBCResultSet[<closed>] closed