Back to Examples
- Binding patterns
- Typed binding pattern
- Wildcard binding pattern
- List binding patterns
- Rest binding pattern in list binding pattern
- Mapping binding pattern
- Rest binding pattern in mapping binding pattern
- Error binding pattern
- Rest binding pattern in error binding pattern
- Single use of typed binding patterns
- Single use of typed binding patterns with on fail clause
- Iterative use of typed binding patterns
- List binding pattern in match statement
- Mapping binding pattern in match statement
- Error binding pattern in match statement
- Query expressions
- Sort iterable objects
- Let clause
- Limit clause
- Join iterable objects
- Outer Join clause
- Query tables
- Create tables with a query
- Create maps with a query
- Create streams with a query
- On conflict clause
- Advanced conflict handling
- Iterate over XML with a query
- Nested query expressions
- Destructure records using a query
- Querying streams
- Aggregation
- JSON type
- Access JSON elements
- Access optional JSON elements
- Match statement with maps
- Convert from user-defined type to JSON
- Convert from table and XML to JSON
- Convert from JSON to user-defined type
- Cast JSON to user-defined type
- Resource method typing
- JSON numbers
- JSON to record
- JSON to record with projection
- JSONPath expressions
- Asynchronous function calls
- Named workers
- Sequence diagrams
- Wait for workers
- Strands
- Named worker return values
- Alternate wait
- Multiple wait
- Named workers and futures
- Inter-worker message passing
- Alternate receive
- Multiple receive
- Conditional send
- Inter-worker failure propagation
- Named worker with on fail clause
- Synchronize message passing
- Asynchronize message passing
- Flush
- Fork
Rollback
If there is a fail or panic in the execution of the block, then the transaction is rolled back. Transaction statement can also contain a rollback statement. Every possible exit from a transaction block must be either commit
, rollback
, fail exit (e.g., from check
), or panic exit.
Rollback does not automatically restore Ballerina variables to values before the transaction.
import ballerina/io;
// Defines the `Update` record type.
type Update record {
int updateIndex;
int stockMnt;
};
public function main() returns error? {
// Creates an array of `Update` records.
Update[] updates = [
{updateIndex: 0, stockMnt: 2000},
{updateIndex: 1, stockMnt: -1000},
{updateIndex: 2, stockMnt: 1500},
{updateIndex: 3, stockMnt: -1000},
{updateIndex: 4, stockMnt: -2000}
];
// This transfer will be rolled back.
io:println(transfer(updates));
// Creates an array of employee salaries.
int[] salaryList = [100, 200, 300, 100];
// This salary increment will be rolled back.
check incrementSalary(salaryList);
int[] salaryList2 = [100, 200, 100, 100];
// This salary increment will be successful.
check incrementSalary(salaryList2);
}
function transfer(Update[] updates) returns error? {
transaction {
// Inside the transaction, call `doUpdate` on each `update` record.
foreach var u in updates {
// If an error is returned, the `transfer` function returns with
// that error and the transaction is rolled back.
check doUpdate(u);
}
// `commit` will not be called because of an implicit rollback.
check commit;
}
return;
}
function doUpdate(Update u) returns error? {
// If the stock amount is less than `-1500`, an error is returned.
if (u.stockMnt < -1500) {
return error("Not enough stocks: ", stockIndex = u.updateIndex);
}
return;
}
function incrementSalary(int[] salaryList) returns error? {
transaction {
foreach int index in 0 ..< salaryList.length() {
salaryList[index] += 100;
}
// If the new total salary exceeds `1000`, then, the rollback statement performs
// rollback on the transaction.
int salarySum = int:sum(...salaryList);
if (salarySum > 1000) {
io:println("Budget exceeded");
rollback;
} else {
io:println("Salary increment successful");
check commit;
}
}
}
$ bal run rollback.balerror("Not enough stocks: ",stockIndex=4)Budget exceededSalary increment successful
PreviousCheck semantics
NextRetry transaction statement