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.
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.
Ax.db.execute("CREATE TABLE IF NOT EXISTS test_work(a SMALLINT NOT NULL);"); Ax.db.execute("INSERT INTO test_work VALUES(1)"); // Transaction is still not commited let rs = Ax.db.executeQuery("SELECT * FROM test_work"); console.log(rs); rs.close(); // Transaction will be commited on exit Ax.db.execute('DROP TABLE test_work');
+------+
|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.
// junit tests have trasaction disbaled by default Ax.db.enableTransactions(); // Transaction succeed Ax.db.execute("DROP TABLE IF EXISTS test_work"); Ax.db.execute("CREATE TABLE IF NOT EXISTS test_work(a SMALLINT NOT NULL)"); // Current transaction rolled back and a new transaction is created. Ax.db.commitWork(); Ax.db.beginWork(); //Ax.db.execute("CREATE TABLE test_work(a SMALLINT NOT NULL)"); Ax.db.execute("INSERT INTO test_work VALUES(1)"); // Transaction fails and exception ocurrs Ax.db.execute("INSERT INTO test_work VALUES(NULL)"); // Rollback is done as script ends with exception // Remember to drop the test table afterwads: Ax.db.execute('DROP TABLE test_work');
Rows are not present in table, as previous script has failed and last transaction is rolled back.
console.log(Ax.db.executeQuery("SELECT * FROM test_work"));
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. If called without any open transaction returns doing nothing. |
Ax.db.rollbackWork() | Roll back current transaction. If called without any open transaction returns doing nothing. |
Ax.db.isOnTransaction() | Return true if an open transaction exists. |
Next example show you how to use transaction manipulation methods:
<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(); } let rs = Ax.db.executeQuery("SELECT * FROM test_work"); console.log(rs); rs.close(); Ax.db.execute('DROP TABLE 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.
<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.
<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