VoIP.info Guide

Asterisk ODBC writes and transactions: commit, rollback and hangup safety

Design one authorized database write with a bounded func_odbc contract, named transaction, explicit completion and deterministic failure treatment.

Reviewed 2026-10-15Current Asterisk database-transaction guidance, latest generated ODBC transaction, commit and rollback references, upstream func_odbc and res_odbc samples, and res_odbc configuration guidance reviewed October 15, 2026; installed Asterisk branch, module packaging, driver, DSN, DBMS, schema, statements, account permissions, isolation support, transaction lifetime, concurrency, idempotency, retry policy and caller treatment remain deployment specific; no host, module, driver, DSN, credential, database, schema, statement, row, transaction, channel or live call was inspected or testedAdvancedDocumentation based · not lab tested

Authorize the state change before opening a transaction

A connected ODBC resource and a successful read do not authorize a database write. Identify the business event, caller or system authority, exact table and columns, allowed old and new states, expected affected-row count, audit record, failure response and database owner before adding a write function. Give the Asterisk account only the required statements on the required objects.

Keep a fixed, named func_odbc.conf function between dialplan data and SQL. Do not expose an arbitrary SQL helper or let caller-controlled data select a table, column or operation. Validate every identifier and value against its business contract, then apply the database-appropriate quote and backslash handling described by the read-lookup guide.

Define the func_odbc write contract precisely

The upstream sample documents writehandle and writesql, with write values available as VAL1 through VALn or the whole VALUE; function arguments remain ARG1 through ARGn. Specify the minimum argument count, value count, null and blank policy, expected affected rows and status-to-dialplan mapping. Treat a statement that ran, a statement that matched zero rows and a statement that changed the intended row as different outcomes.

insertsql is documented as a second statement run when the initial write succeeds but reports zero affected rows. That is a trigger condition, not a universal atomic upsert guarantee. Concurrency, uniqueness, validation and any update-or-insert invariant still belong to the selected DBMS, schema and reviewed statement or stored routine.

Create and select a named transaction deliberately

Asterisk uses ODBC(transaction,<database>) to create or select a transaction ID, and the transaction name selects which transaction is active for later dialplan functions. Record the database connection name, transaction ID, creating channel, start point and every statement intended to participate. Do not confuse the transaction ID with the DSN, database name or row identifier.

If more than one transaction can exist on a channel, set the intended active transaction before each dependent operation and keep transaction IDs unique within that call flow. The default separate-connection behavior of func_odbc and the optional single_db_connection setting are connection policies, not substitutes for a documented transaction boundary.

Commit only after every acceptance check passes

Asterisk documents ODBC_Commit() and ODBC_Rollback() as completing a specified transaction ID or the current active transaction when no ID is supplied. Prefer an explicit transaction ID in reusable or branching dialplan so a change in active state cannot complete the wrong unit of work. Commit only after the statement statuses, affected-row expectations and business checks all pass; route every other branch to an explicit rollback.

A successful commit still does not prove downstream caller treatment, audit delivery or replica visibility. Preserve database result, completion application, next dialplan priority and caller outcome as separate observations. Never retry an uncertain commit blindly; first determine whether the database accepted the transaction.

Make hangup and early exit fail closed

Asterisk documents forcecommit as controlling automatic commit when the channel hangs up and states that the DSN default is false. Its transaction guide says an open transaction is automatically rolled back at channel destruction when it was not explicitly committed and forcecommit is not enabled. Keep that rollback-on-destruction behavior as the safety default, while still using explicit rollback on known failure paths.

Map caller hangup, transfer, channel replacement, invalid input, database timeout, zero-row result and dialplan exception before production. Do not use forcecommit to compensate for missing branch handling: it can turn an interrupted call path into a persisted change without the final acceptance checks.

Choose isolation and concurrency controls with the database owner

The ODBC transaction function lists read_uncommitted, read_committed, repeatable_read and serializable, while Asterisk warns that driver and database support varies. Select only a level supported by the installed driver and DBMS, document what concurrent readers and writers may observe, and test lock wait, deadlock and timeout behavior under the approved database policy.

Use database constraints or a reviewed stored routine for invariants that must survive concurrent calls. Where a call flow can repeat after an uncertain result, define an idempotency key or other server-side duplicate guard and a reconciliation path. Those are deployment designs, not guarantees supplied by Asterisk. No transaction, isolation level, retry, rollback or caller outcome was tested for this guide.

Sources & applicability

Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.

Examples require adaptation to your topology. No live PBX or hardware testing is claimed.