Summary

  • RFC 3525 guaranteed sequential command processing inside one transaction, while separate transactions could execute in any order or simultaneously—even inside one message.
  • Pending notices, retransmission control, response acknowledgements and at-most-once handling bounded delivery and duplication; they did not create a shared causal clock or prove a media outcome.

The protocol needed that distinction because its gateway was already divided. A Media Gateway Controller held call-control intelligence; a Media Gateway handled media-facing resources. RFC 3525 supplied a language between them: Contexts collected related Terminations, Actions addressed one Context, and Commands added, modified, moved, subtracted or audited state.

The hierarchy looked nested enough to invite a false inference. A Message contained Transactions. A Transaction contained Actions. An Action contained Commands. Reading down the page, it was easy to imagine that every outer container also imposed order on everything within it.

RFC 3525 drew the line elsewhere. Commands in one Transaction were executed sequentially. The first failing non-optional Command stopped the remaining Commands in that Transaction. If the failed Command was marked Optional, later Commands could continue. That was a real ordering guarantee, but it ended at the transaction boundary.

Separate Transactions were expressly unordered. The gateway could execute them in any order or simultaneously. Putting Transactions A, B and C in the same Message did not turn the Message into a batch with one application clock. The specification called the Message essentially a transport mechanism. Replies to A and C could return together while B arrived later in another Message.

This was not an omission. Parallelism let a controller act promptly on independent Terminations. One process could manage one group of Terminations while another process handled another. Globally serializing unrelated work would have made the protocol simpler to narrate but slower to run.

The cost appeared when the work was not independent. Suppose one transaction asked the gateway to Add a Termination and another immediately asked it to Modify that Termination. Send order did not prove execution order. If the Modify arrived at its operational turn before the Add had established the target state, the later-looking instruction could fail first.

RFC 3525 therefore gave the controller a discipline. On one Termination, normally only one Add, Modify or Move should be outstanding unless the dependent Commands were placed in the same Transaction. The application had to create the stronger ordering it needed. The network envelope did not infer dependency from proximity.

Subtract made the race more visible. The specification allowed it to be issued at any time. A Modify could consequently arrive for a Termination already subtracted. The gateway should ignore that Modify and return an error. A clean request trace could therefore preserve send order while the gateway's state history told a different story.

Notify had its own version of the problem. A notification could be delayed until after the controller transmitted a new EventsDescriptor. On a transport without in-sequence delivery, such as UDP, the specification advised no more than one outstanding Notify per Termination. The receipt needed a transaction identifier, Termination identity, event-request identity and time—not merely a packet position.

Failure within a Transaction was also narrower than the everyday meaning of “transaction.” A failed Command was to restore the state before that Command's attempted execution as far as possible. The document did not promise a database-style rollback of every earlier Command that had succeeded. Its TransactionReply returned values for successful Commands and an error descriptor for the failed one.

Wildcard execution made partial evidence unavoidable. A Command with a wildcarded TerminationID was attempted against every match. The reply included a result for each. If one match failed, later Commands in the Transaction were not attempted. The controller could therefore receive a mixture of successful wildcard instances, one or more errors and absent later work. “Transaction failed” was too coarse to reconstruct reality.

TransactionPending was equally precise. It meant that processing had not completed but remained active. It restarted the sender's application timer. It did not say which Command had run, whether any state change would survive, or whether another Transaction had overtaken it.

The transport annex handled another problem: a lost reply could cause a request to be repeated. Transaction identifiers, retained replies, response acknowledgements and retransmission rules supported at-most-once behavior. They helped distinguish a repeat from a new operation. They did not establish order between two different Transactions, and at-most-once execution was not exactly-once service delivery.

Even a successful reply stopped short of the user. It could prove that the gateway processed a Command and returned specified state. An Audit could examine Context or Termination properties. Neither receipt alone proved that packets followed the intended bearer path, that audio was decoded, or that a person heard the call.

The document's institutional history reinforces the boundary. RFC 3525 replaced RFC 3015 in 2003 and reflected joint work between the IETF Megaco Working Group and ITU-T Study Group 16. In 2008, RFC 5125 moved it to Historic because the ITU-T had continued H.248.1 through corrections and later versions. RFC 3525 can explain the design's ordering model; it must not be presented as the current deployment specification.

The live IANA Megaco/H.248 registry tells another bounded truth. Package identifiers, errors, reasons and profiles remain coordinated under later references. A registry can preserve shared names after the specification around them moves. It cannot show which version one gateway runs or how two transactions raced inside it.

RFC 3525's durable lesson is not “always serialize.” It is to put the guarantee at the smallest layer that owns the dependency. Independent Terminations may proceed in parallel. Dependent Commands belong together or must wait for a prior receipt. The shared protocol names the minimum common order; running controllers remain responsible for the stronger causal story they need.

Sources