Skip to content

Add commit and rollback functionality for transactions#21

Draft
twisti-dev wants to merge 3 commits into
version/26.1from
feat/rollbackable-transactions
Draft

Add commit and rollback functionality for transactions#21
twisti-dev wants to merge 3 commits into
version/26.1from
feat/rollbackable-transactions

Conversation

@twisti-dev

Copy link
Copy Markdown
Contributor

Database Migration required

ALTER TABLE transactions ADD ignore_minimum_amount BOOLEAN DEFAULT FALSE NOT NULL;
ALTER TABLE transactions ADD `state` VARCHAR(16) DEFAULT 'COMMITTED' NOT NULL;
ALTER TABLE transactions ADD expires_at TIMESTAMP(6) NULL;
ALTER TABLE transactions ADD operation_id UUID NULL;
CREATE INDEX transactions_state_expires_at ON transactions (`state`, expires_at);
CREATE INDEX transactions_operation_id_state_expires_at ON transactions (operation_id, `state`, expires_at);
ALTER TABLE transactions MODIFY COLUMN updated_at TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) NOT NULL;
ALTER TABLE transactions ADD CONSTRAINT transactions_pending_has_expiration CHECK ((`state` <> 'PENDING') OR (expires_at IS NOT NULL));
ALTER TABLE transactions ADD CONSTRAINT transactions_pending_has_operation CHECK ((`state` <> 'PENDING') OR (operation_id IS NOT NULL));

This pull request introduces a comprehensive, durable pending transaction system to the financial microservice, enabling explicit commit, rollback, and expiration semantics for transactions. It adds new API types and methods to support pending reservations, extends the database schema to track transaction state and expiration, and documents the new workflows and their concurrency, timeout, and error handling behaviors.

Pending Transaction Lifecycle and API Enhancements:

  • Added support for durable pending reservations with explicit commit, rollback, and expiration, including new API methods (commit, rollback, refresh) and result types (TransactionCommitResult, TransactionRollbackResult, PendingTransactionResult). [1] [2] [3] [4] [5] [6] [7]
  • Introduced a new exception type, PendingReservationTimeoutException, to handle indeterminate reservation outcomes and support reconciliation by transaction identifier.
  • Added PendingTransactions configuration object with a default timeout for pending reservations.

Database Schema Changes:

  • Extended the transactions table with new columns for state, expires_at, operation_id, and ignore_minimum_amount, added relevant indexes, and introduced constraints to ensure pending transactions have expiration and operation IDs.

Documentation Updates:

  • Updated README.md to explain the new pending transaction workflows, including the convenience and explicit lifecycle APIs, balance semantics, concurrency, and failure handling strategies. [1] [2]

These changes collectively provide robust support for external operations that require atomic reservation, commit, or rollback of funds, improving reliability and auditability of financial workflows.

…ctions

- implement commit and rollback methods in TransactionService interface
- create TransactionRpcService for handling transaction lifecycle operations
- add TransactionState enum to manage transaction states
- introduce TransactionLifecycle for managing transaction state transitions
- create PendingTransactions object for shared configuration of pending transactions
@twisti-dev twisti-dev self-assigned this Jul 15, 2026
@twisti-dev twisti-dev added the status: blocked Issue or Request is waiting on some other issue or change. label Jul 15, 2026
… pending execution results

- introduce transactionOrNull property to retrieve associated transaction or null
- add valueOrNull property to get the result value or null based on execution outcome
- implement isCompleted property to check if the transaction reached a committed state
@twisti-dev

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1f844aa49

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

require(transactions.isNotEmpty()) { "Cannot write an empty transaction list" }

val context = writeContext(transactions) ?: return UnknownAccountOrCurrency
val expiresAt = timeoutMillis?.let(context.now::plusMillis)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject timeouts that overflow Instant

When a caller passes a very large but finite positive Duration, the client accepts it as a millisecond value and the microservice reaches this plusMillis call; if the resulting expiration is outside Instant's range, Instant.plusMillis throws instead of returning PendingTransactionResult.InvalidTimeout. This makes oversized pending reservations fail as an RPC/service exception even though the public timeout contract says invalid durations are reported as typed reservation failures.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: blocked Issue or Request is waiting on some other issue or change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant