Transactions
Volt provides transaction support for atomic database operations. All operations return a Result<T, VoltError> type for explicit error handling.
Getting a Transaction
java
Transaction tx = volt.beginTransaction();Transactions implement AutoCloseable, so you can use try-with-resources:
java
try (Transaction tx = volt.beginTransaction()) {
// operations...
tx.commit();
}Result Type
All transaction operations return Result<T, VoltError> instead of throwing exceptions:
java
Result<User, VoltError> result = tx.findById(User.class, 1L);
if (result.isOkay()) {
User user = result.getValue();
// use user
} else {
VoltError error = result.getError();
System.err.println(error.getMessage());
}CRUD Operations
Save (Insert or Upsert)
Saves an entity. Inserts if the primary key is null and auto-generated, otherwise performs an upsert:
java
User user = new User();
user.setUsername("john");
user.setEmail("john@example.com");
Result<User, VoltError> result = tx.save(user);Find by ID
java
Result<User, VoltError> result = tx.findById(User.class, 1L);Find All
Retrieve all entities of a type:
java
Result<List<User>, VoltError> result = tx.findAll(User.class);Find by Field
Simple field equality queries:
java
// Find first matching (returns Optional)
Result<Optional<User>, VoltError> result = tx.findFirstBy(User.class, "email", "john@example.com");
// Find exactly one (errors if none or multiple found)
Result<User, VoltError> result = tx.findOneBy(User.class, "username", "john");
// Find all matching
Result<List<User>, VoltError> result = tx.findAllBy(User.class, "status", "active");Find with Query
For complex queries, pass a Query object:
java
Query query = Query.where("status").eq("active")
.and("age").gte(18);
// Find first matching
Result<Optional<User>, VoltError> first = tx.findFirstBy(User.class, query);
// Find exactly one
Result<User, VoltError> one = tx.findOneBy(User.class, query);
// Find all matching
Result<List<User>, VoltError> all = tx.findAllBy(User.class, query);Delete
Delete by entity or by ID:
java
// Delete entity
Result<Void, VoltError> result = tx.delete(user);
// Delete by ID
Result<Void, VoltError> result = tx.deleteById(User.class, 1L);Commit and Rollback
Commit
Persist all changes made within the transaction:
java
Result<Void, VoltError> result = tx.commit();
if (result.isOkay()) {
System.out.println("Transaction committed");
} else {
System.err.println("Commit failed: " + result.getError().getMessage());
}Rollback
Discard all changes:
java
Result<Void, VoltError> result = tx.rollback();Complete Examples
Creating Related Entities
java
try (Transaction tx = volt.beginTransaction()) {
User user = new User();
user.setUsername("john");
user.setEmail("john@example.com");
Result<User, VoltError> userResult = tx.save(user);
if (!userResult.isOkay()) {
tx.rollback();
return;
}
Profile profile = new Profile();
profile.setUserId(userResult.getValue().getId());
profile.setBio("Software developer");
Result<Profile, VoltError> profileResult = tx.save(profile);
if (!profileResult.isOkay()) {
tx.rollback();
return;
}
tx.commit();
}Money Transfer
java
public Result<Void, VoltError> transfer(Long fromId, Long toId, BigDecimal amount) {
try (Transaction tx = volt.beginTransaction()) {
Result<Account, VoltError> fromResult = tx.findById(Account.class, fromId);
if (!fromResult.isOkay()) {
return Result.failure(fromResult.getError());
}
Result<Account, VoltError> toResult = tx.findById(Account.class, toId);
if (!toResult.isOkay()) {
return Result.failure(toResult.getError());
}
Account from = fromResult.getValue();
Account to = toResult.getValue();
if (from.getBalance().compareTo(amount) < 0) {
tx.rollback();
return Result.failure(new VoltError("Insufficient funds"));
}
from.setBalance(from.getBalance().subtract(amount));
to.setBalance(to.getBalance().add(amount));
tx.save(from);
tx.save(to);
return tx.commit();
}
}Query and Update
java
try (Transaction tx = volt.beginTransaction()) {
Query query = Query.where("status").eq("pending")
.and("createdAt").lt(cutoffDate);
Result<List<Order>, VoltError> result = tx.findAllBy(Order.class, query);
if (result.isOkay()) {
for (Order order : result.getValue()) {
order.setStatus("expired");
tx.save(order);
}
tx.commit();
}
}Method Reference
| Method | Return Type | Description |
|---|---|---|
save(entity) | Result<T, VoltError> | Insert or upsert an entity |
findById(class, id) | Result<T, VoltError> | Find by primary key |
findAll(class) | Result<List<T>, VoltError> | Find all entities |
findFirstBy(class, field, value) | Result<Optional<T>, VoltError> | Find first by field |
findOneBy(class, field, value) | Result<T, VoltError> | Find exactly one by field |
findAllBy(class, field, value) | Result<List<T>, VoltError> | Find all by field |
findFirstBy(class, query) | Result<Optional<T>, VoltError> | Find first by query |
findOneBy(class, query) | Result<T, VoltError> | Find exactly one by query |
findAllBy(class, query) | Result<List<T>, VoltError> | Find all by query |
delete(entity) | Result<Void, VoltError> | Delete an entity |
deleteById(class, id) | Result<Void, VoltError> | Delete by primary key |
commit() | Result<Void, VoltError> | Commit the transaction |
rollback() | Result<Void, VoltError> | Rollback the transaction |
close() | void | Release the connection |