Skip to main content

Transactions

dbVisitor provides lightweight local transaction support for grouping multiple database operations into one commit or rollback boundary. It is useful for workflows such as creating an order and its items together, writing a master row plus detail rows, or running one step in an independent transaction.

A transaction is managed by TransactionManager, and one manager is bound to one DataSource. Inside a transaction, dbVisitor lets JdbcTemplate, Mapper, BaseMapper, LambdaTemplate, and other APIs reuse the database connection bound to the current thread. The transaction is then committed or rolled back at the end.

info

Transactions require database and JDBC driver support and cannot be used with non-transactional adapters. dbVisitor manages local transactions, not distributed transactions. Multiple DataSource instances can each have transaction interceptors, but dbVisitor does not add two-phase commit between databases.

Choose an API​

APIBest forNot best forEntry
Annotation-basedClear Service method boundaries and clean business codeNo proxy/interceptor, or dynamic transaction boundariesAnnotation-based
Transaction templateA local code block that should commit or roll back automaticallyManually controlling multiple transaction statusesTransaction template
ProgrammaticFull control over begin, commit, and rollBackRegular business methods with repetitive try/catch codeProgrammatic

Typical recommendation:

  • In Spring, Solon, Guice, or Hasor projects, prefer annotation-based transactions.
  • In plain Java programs, scripts, or local transaction blocks, prefer transaction templates.
  • Use programmatic transactions only when you need to control transaction statuses directly.

A Complete Effect​

The example assumes a database with sequences and local transactions, such as H2. Create the tables and sequence first, then invoke the method through a transaction proxy. The method makes order creation atomic: order, item, and stock update must succeed together. If any step fails, all steps roll back.

OrderService.java
import net.hasor.dbvisitor.jdbc.JdbcTemplate;
import net.hasor.dbvisitor.transaction.Transactional;

public class OrderService {
private final JdbcTemplate jdbcTemplate;

public OrderService(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

@Transactional
public long createOrder(long userId, long skuId, int quantity) throws java.sql.SQLException {
Long orderId = jdbcTemplate.queryForObject(
"select next value for seq_order",
Long.class
);

jdbcTemplate.executeUpdate(
"insert into orders(id, user_id) values(?, ?)",
new Object[] { orderId, userId }
);
jdbcTemplate.executeUpdate(
"insert into order_item(order_id, sku_id, quantity) values(?, ?, ?)",
new Object[] { orderId, skuId, quantity }
);
jdbcTemplate.executeUpdate(
"update sku_stock set quantity = quantity - ? where sku_id = ?",
new Object[] { quantity, skuId }
);
return orderId;
}
}

If the stock update throws after the order item is inserted, the interceptor marks the transaction for rollback. The final effect is that no partial order data is committed.

Code Structure​

Transaction-related APIs live under net.hasor.dbvisitor.transaction:

TypePurpose
@TransactionalDeclares a method or class as transactional
PropagationControls how a method joins, creates, or suspends transactions
IsolationControls database isolation level
TransactionManagerCore begin/commit/rollBack API
TransactionStatusState returned by one transaction begin operation
TransactionTemplateCallback-style transaction boundary
TransactionTemplateManagerDefault TransactionTemplate implementation
TransactionHelperCreates managers from DataSource or annotation proxies
LocalTransactionManagerDefault local transaction manager implementation
DataSource
|
v
LocalTransactionManager -- begin/commit/rollBack --> TransactionStatus
|
+-- TransactionTemplateManager.execute(...)
|
+-- TransactionInterceptor --> @Transactional

Learn More​