RFC 2372

Transaction Internet Protocol - Requirements and Supplemental Information

๐Ÿ“… published July 1998, from ietf

RFC 2372: Transaction Internet Protocol - Requirements and Supplemental Information ๐Ÿ’–

Network Working Group โœจ Informational ๐ŸŽ€ July 1998

  • Authors: K. Evans and J. Klein (Tandem Computers), and J. Lyon (Microsoft) ๐Ÿ‘ฏโ€โ™€๏ธ
  • Category: Informational ๐Ÿ“š
  • Date: July 1998 ๐Ÿ“…
  • Obsoletes / Updates: this title block doesn't list any RFCs as obsoleted or updated ๐Ÿ™ƒ

Status of this Memo ๐Ÿซถ

Okay so this memo is just here to inform the internet community. It is NOT an Internet standard of any kind, so no pressure. Distribution is unlimited, meaning go share it bestie ๐Ÿ’Œ

Copyright (C) The Internet Society (1998). All Rights Reserved. ๐Ÿ”’

Abstract ๐ŸŒธ

This doc describes the purpose (usage scenarios) and requirements for the Transaction Internet Protocol [1]. The goal is to help pin down the features and functions the protocol needs. It also gives supplemental info to help you understand TIP and actually implement it, which is so important ๐Ÿงš

Table of Contents ๐Ÿ—บ๏ธ

   1.  Introduction                                               2
   2.  The Transaction Internet Protocol                          3
   3.  Scope                                                      4
   4.  Anticipated Usage of TIP                                   4
   5.  TIP Compliant Systems                                      4
   6.  Relationship to the X/Open DTP Model                       5
   7.  Example TIP Usage Scenario                                 5
   8.  TIP Transaction Recovery                                   9
   9.  TIP Transaction and Application Message Serialisation     10
   10. TIP Protocol and Local Actions                            10
   11. Security Considerations                                   11
   12. TIP Requirements                                          11
       References                                                14
       Authors' Addresses                                        15
       Comments                                                  15
   A.  An Example TIP Transaction Manager API                    16
       Full Copyright Statement                                  24

1. Introduction โœจ

Okay transactions are literally such a useful programming paradigm ๐Ÿ’… They make distributed apps so much easier to write. When transactions are involved, no matter how many distributed application components are part of one unit-of-work, the possible outcomes shrink to just two. Either all of the work completed successfully, or none of it did. This is called atomicity, and it's the whole main character energy of transactions ๐Ÿ‘‘ Because of that, programmers don't have to juggle a bunch of possible failure scenarios, so app programming gets way less complex ๐Ÿ™Œ Usually the transaction semantics come from underlying system infrastructure (think Transaction Processing Monitors and/or Databases). That infrastructure handles failures and runs the recovery actions needed to guarantee atomicity. Transactions are what make reliable distributed apps possible, which would otherwise be super hard, if not impossible ๐Ÿฅน

Now, a key tech for distributed transactions is the two-phase commit protocol (2-pc) ๐Ÿ”‘ 2-pc protocols have been used in commercial Transaction Processing (TP) systems for years and are well understood. For example, the LU6.2 2-pc (syncpoint) protocol was first implemented more than 12 years ago ๐Ÿ•ฐ๏ธ Today, a bunch of different 2-pc protocols are supported by a variety of TP monitor and database products. 2-pc is used between the components in a distributed unit-of-work (transaction) to make sure all parties agree on the outcome of that work, regardless of any failure ๐Ÿค

Both standard and proprietary 2-pc protocols exist today ๐ŸŒˆ These protocols typically use a "one-pipe" model. That means the transaction and application protocols are tightly integrated and run over the same communications channel. An application may only use the particular communications mechanism tied to the transaction protocol. The standard protocols (OSI TP, LU6.2) are complex, have a large footprint, and need extensive configuration and administration. So they aren't very widely deployed ๐Ÿ˜ฌ The net result is restricted application flexibility and interoperability when transactions are involved. Apps may want to use communications protocols that have no transactional variants (HTTP, for example), and they might be deployed in very heterogeneous application environments ๐Ÿซ 

In summary, transactions make distributed apps way easier to program, and 2-pc is a key transactional technology. But current 2-pc protocols only offer transaction semantics to a limited set of applications. Those apps have to run in a special-purpose (complex, homogeneous) infrastructure and use a particular set of intercommunication protocols. These restrictions limit how widely the transaction paradigm gets used, which holds back new distributed business applications ๐Ÿ˜ญ

(See [2] for more information re transactions, atomicity, and two-phase commit protocols in general.) ๐Ÿ“–

2. The Transaction Internet Protocol (TIP) ๐Ÿฆ‹

TIP is a 2-pc protocol meant to give ubiquitous distributed transaction support in a heterogeneous (networked) environment. It removes the restrictions of current 2-pc protocols and makes room for new distributed business applications. It's giving freedom ๐Ÿ•Š๏ธ

This goal is mainly achieved by meeting two key requirements:

  1. Keep the protocol simple (yet functionally sufficient). If the protocol is complex, it won't be widely deployed or quickly adopted. Simplicity also means it suits a wide range of application environments ๐Ÿงธ
  2. Enable the protocol to be used with any application communications protocol (for example, HTTP). This means heterogeneous environments can take part in distributed work ๐ŸŒ

TIP doesn't reinvent the 2-pc protocol itself. The well-known presumed-abort 2-pc protocol is used as the basis. The real novelty and utility of TIP is how it separates from the application communications protocol. That's the two-pipe model ๐ŸŽ€

      +-------------+ Application Communication +-------------+
      | Application |---------------------------| Application |
      |   Program   |         "Pipe 1"          |   Program   |
      +-------------+                           +-------------+
             |                                         |
             | TIP TM API                   TIP TM API |
             |                                         |
    +-----------------+   TIP 2-pc Protocol   +-----------------+
    | TIP Transaction |-----------------------| TIP Transaction |
    |     Manager     |       "Pipe 2"        |     Manager     |
    +-----------------+                       +-----------------+

                 Fig 1: The two-pipe nature of TIP

3. Scope ๐Ÿ”

TIP doesn't describe how business transactions or electronic commerce are supposed to be conducted on the internet. It only specifies the 2-pc transaction protocol, which is a helper for building those kinds of apps (for example, TIP doesn't provide a mechanism for non-repudiation) ๐Ÿงพ Protocols like that might be a topic for later IETF work, once the requirements for general electronic commerce are better understood. TIP doesn't rule out defining these protocols later ๐Ÿ”ฎ

TIP doesn't specify Application Programming Interfaces. That said, an example TIP TM API is included in this document (Appendix A) just to help with understanding ๐Ÿ“š

4. Anticipated Usage of TIP ๐ŸŒŸ

As mentioned above, transactions are a super useful tool for simplifying distributed app programming. So TIP is aimed at any application that involves distributed work ๐Ÿ’ซ Those apps might have components running inside a single system, across a corporate intranet, across the internet, or in any other distributed system setup. The app can be "enterprise" class (needing high levels of performance and availability), or it can be less demanding. TIP is meant to be broadly applicable, fitting the requirements of any app type that would benefit from transaction semantics ๐Ÿ’…

5. TIP Compliant Systems ๐Ÿงฉ

There are two classes of TIP compliant Transaction Manager systems:

  1. Client-only systems. These provide an application interface to demarcate TIP transactions, but they don't offer access to local recoverable resources. This lightweight implementation is useful for systems that only host client applications (desktop machines, for example). Client systems like this may be unreliable, so they aren't appropriate as transaction coordinators. Their unavailability might leave resources on other transaction participant systems locked and unavailable ๐Ÿ˜ฑ These so-called "volatile client" systems hand off the job of coordinating the transaction (and recovering from failures) to other "full" (server) TIP system implementations. For these lightweight systems, only the TIP IDENTIFY, BEGIN, COMMIT, and ABORT commands are needed, and no transaction log is required ๐Ÿชถ
  2. Server systems. These offer all the above support, plus TIP transaction coordination and recovery services. They may also provide access to recoverable resources (for example, relational databases). Server systems support all TIP commands and provide a recoverable transaction log ๐Ÿฐ

A TIP compliant Transaction Manager (TM) will also supply application programming interfaces to demarcate transactions (for example, the X/Open TX interface [3]). It also supplies commands to generate TIP URLs, to PUSH/PULL TIP transactions, and to set the current TIP transaction context ๐Ÿ› ๏ธ TIP support can be added to TMs that already have APIs and 2-pc protocols. Transactions may also comprise both proprietary and TIP transaction branches. It's assumed existing TM implementations will provide "TIP gateway" facilities that coordinate between TIP and other transaction protocols ๐ŸŒ‰

6. Relationship to the X/Open DTP Model ๐Ÿง 

The X/Open Distributed Transaction Processing (DTP) Model [4] defines four components: 1) Application Program (AP), 2) Transaction Manager (TM), 3) Resource Manager (RM), and 4) Communications Resource Manager (CRM). In this model, TIP defines a TM to TM interoperability protocol that is independent of application communications. (X/Open specifies no equivalent protocol. There, all transaction and application communication happens between CRMs, which is the one-pipe model.) Programmatic interfaces between the AP and TM/RM are unaffected by TIP and may be used with it. The TM to RM interaction is defined via the X/Open XA interface specification [5]. TIP is compatible with XA, and a TIP transaction may comprise applications accessing multiple RMs where the XA interface is used to coordinate the RM transaction branches ๐Ÿฅฐ

7. Example TIP Usage Scenario ๐Ÿงš

okay so the big one is that a typical internet usage of TIP is expected to use the agency model ๐Ÿ’… in this model the client node itself isn't directly involved in the TIP protocol at all, and it doesn't need the services of a local TIP TM. instead, an agency (server) application handles the dialogue with the client and is responsible for coordinating the TIP transaction. the agency works with other service providers to deliver the service to the client, kinda like how a Travel Agency acts as the middle person between airlines/hotels/etc and the customer ๐Ÿงณ and the best part? the agency is trusted by the service providers, and there are way fewer agencies than user clients, so issues of security and performance are reduced ๐Ÿ”ฅ

Consider a Travel Agency example. a client running a web browser on a network PC accesses the Travel Agency web page ๐ŸŒธ via pages served up by the agency (which may in turn be constructed from pages provided by the airline and hotel servers), the client creates an itinerary involving flights and hotel choices โœˆ๏ธ finally, the client clicks the "make reservation" button. at this point the following sequence of events occurs (user-written application code is invoked by the various web servers, via any of the standard or proprietary techniques available (e.g. CGI)):

  1. The travel agency begins a local transaction, and gets a TIP URL for this transaction (both of these functions are performed using the API of the local TM. e.g. tip_xid_to_url() would return the TIP URL for the local transaction). The TIP URL contains the listening endpoint IP address of the local TM and the transaction identifier of the local transaction. ๐Ÿ†”
  2. The travel agency application sends a request to the airline server (via some protocol (e.g. HTTP)), requesting the book_flight service, passing the flights selected by the client, and the TIP URL (obtained in 1. above).
  3. The request is received by the airline server, which invokes the book_flight application. This application retrieves the TIP URL from the input data, and passes this on a tip_pull() API request to its local TM. The tip_pull() function causes the following to occur:
    • a. the local TM creates a local transaction (under which the work will be performed),
    • b. if a TIP connection does not already exist to the superior (travel agency) TM (as identified via the IP address passed in the TIP URL), one is created and an IDENTIFY exchange occurs (if multiplexing is to be used on the connection, this is followed by a MULTIPLEX exchange),
    • c. a PULL command is sent to the superior TM,
    • d. in response to the PULL, the superior TM associates the subordinate (airline) TM with the transaction (by associating the connection with the transaction), and sends a PULLED response to the subordinate TM,
    • e. the subordinate TM returns control to the book_flight application, which is now executing in the context of the newly created local transaction. ๐Ÿฆ‹
  4. The book_flight application does its work (which may involve access to a recoverable resource manager (e.g. an RDBMS), in which case the local TM will associate the RM with the local transaction (via the XA interface or whatever)). ๐Ÿ’ป
  5. The book_flight application returns to the travel agency application indicating success. โœ…
  6. Steps 2-5 are then repeated with the hotel server book_room application. at the conclusion of this, the superior TM has registered two subordinate TMs as participants in the transaction, there are TIP connections between the agency TM and the airline and hotel TMs, and there are inflight transactions at the airline and hotel servers. [Note that steps 2-5 and 6 could be performed in parallel.] ๐Ÿจ
  7. The travel agency application issues a "commit transaction" request (using the API of the local TM). The local TM sends a PREPARE command on the TIP connections to the airline and hotel TMs (as these are registered as subordinate transaction participants). ๐Ÿ“
  8. The TMs at the airline and hotel servers perform the necessary steps to prepare their local recoverable resources (e.g. by issuing xa_prepare() requests). If successful, the subordinate TMs change their TIP transaction state to Prepared, and log recovery information (e.g. local and superior transaction branch identifiers, and the IP address of the superior TM). The subordinate TMs then send PREPARED commands to the superior TM. ๐Ÿ”’
  9. If both subordinates respond PREPARED, the superior TM logs that the transaction is Committed, with recovery information (e.g. local and subordinate transaction identifiers, and subordinate TM IP addresses). The superior TM then sends COMMIT commands on the two subordinate TIP connections. ๐ŸŽ‰
  10. The TMs at the airline and hotel servers perform the necessary steps to commit their local recoverable resources (e.g. by issuing xa_commit() requests). The subordinate TMs forget the transaction. The subordinate TMs then send COMITTED commands to the superior TM. ๐Ÿ’œ
  11. The superior TM forgets the transaction. The TIP connections between the superior and subordinate TMs return to Idle state (not associated with any transaction). The superior TM returns success to the travel agency application "commit transaction" request. ๐Ÿ‘‘
  12. The travel agency application returns "reservation made" to the client. ๐ŸŽ€

This example illustrates the use of PULL. If PUSH were to be used instead, events 2) and 3) above would change as follows:

  1. The travel agency application:
    • a. passes the TIP URL obtained in 1. above, together with the listening endpoint address of the TM at the airline server, to its local TM via a tip_push() API request. The tip_push() function causes the following to occur:
      • i. if a TIP connection does not already exist to the subordinate (airline server) TM (as identified via the IP address passed on the tip_push), one is created and an IDENTIFY exchange occurs (if multiplexing is to be used on the connection, this is followed by a MULTIPLEX exchange),
      • ii. a PUSH command is sent to the subordinate TM,
      • iii. in response to the PUSH, the subordinate TM creates a local transaction, associates this transaction with the connection, and sends a PUSHED response to the superior TM,
      • iv. in response to the PUSHED response, the superior TM associates the subordinate TM with the transaction,
      • v. the superior TM returns control to the travel agency application.
    • b. the travel agency application sends a request to the airline server (via some protocol (e.g. HTTP)), requesting the book_flight service, passing the flights selected by the client, and the TIP URL (obtained in 1 above).
  2. The request is received by the airline server, which invokes the book_flight application. This application retrieves the TIP URL from the input data, and passes this on a tip_pull() API request to its local TM. Since the local TM has already "seen" this URL (it was already pushed), it simply returns to the book_flight application, which is now executing in the context of the previously created local transaction. ๐Ÿ”

[Note that although in this example the transaction coordinator role is performed by a node which is also a participant in the transaction (the Travel Agency), other configurations are possible (e.g. where the transaction coordinator role is performed by a non-participant 3rd-party node).]


8. TIP Transaction Recovery ๐Ÿ›Ÿ

until the transaction reaches the Prepared state, any failure results in the transaction being aborted. if an error occurs once the transaction has reached the Prepared state, then transaction recovery must be performed. recovery behaviour is different for superior and subordinate; the details depend upon the outcome of the transaction (committed or aborted), and the precise point at which failure occurs. ๐Ÿ˜ฌ

In the travel agency application for example, if the connection to the hotel server fails before the COMMIT command has been received by the hotel TM, then (once the connection is restored):

  1. The superior (travel agency) TM sends a RECONNECT command (passing the subordinate transaction identifier (recovered from the transaction log if necessary)).
  2. The subordinate (hotel) TM responds RECONNECTED (since it never received the COMMIT command, and still has the transaction in Prepared state (if the failure had occurred after the subordinate had responded COMMITTED, then the subordinate would have forgotten the transaction, and responded NOTRECONNECTED to the RECONNECT command)). ๐Ÿค
  3. The superior TM sends a COMMIT command. The subordinate TM commits the transaction and responds COMMITTED. The transaction is now resolved. โœจ
  4. If the subordinate TM restores the connection to the superior TM before receiving a RECONNECT command, then it may send a QUERY command. In this case, the superior TM will respond QUERIEDEXISTS, and the subordinate TM should wait for the superior to send a RECONNECT command. If the transaction had been aborted, then the superior may respond QUERIEDNOTFOUND, in which case the subordinate should abort the transaction (note that the superior is not obliged to send a RECONNECT command for an aborted transaction (i.e. it could just forget the transaction after sending ABORT and before receiving an ABORTED response)). ๐Ÿ™ˆ
There are failure circumstances in which the client application (the one calling "commit") may not receive a response indicating the final outcome of the transaction (even though the transaction itself is successfully completed). This is a common problem, and one not unique to TIP. In such circumstances, it is up to the application to ascertain the final outcome of the transaction (a TIP TM may facilitate this by providing some implementation specific mechanism. e.g. writing the outcome to a user-log). ๐Ÿ““

9. TIP Transaction and Application Message Serialisation ๐ŸŽ€

a relationship exists between TIP commands and application messages: a TIP transaction must not be committed until it is certain that all participants have properly registered, and have finished work on the transaction. because of the two-pipe nature of TIP, this behaviour cannot necessarily be enforced by the TIP system itself (although it may be possible in some implementations). it is therefore incumbent upon the application to behave properly. generally, an application must not: ๐Ÿ™

  1. call it's local TMs "commit" function when it has any requests associated with the transaction still outstanding.
  2. positively respond to a transactional request from a partner application prior to having registered it's local TM with the transaction.

10. TIP Protocol and Local Actions ๐ŸŽ€

okay bestie, so to keep transaction atomicity properly guaranteed, a TIP system has to do some local actions at certain points in the protocol exchange ๐Ÿงš these are all about making and deleting transaction log-records. those are the info that survives failures so transaction recovery can run correctly ๐Ÿ’พ

heads up: the stuff below about how TIP and logging events fit together is advisory, not definitive. if you want the deep dive, go check [2] ๐Ÿ“š

  1. before sending a PREPARED response, the system should create a prepared-recovery-record for the transaction.
  2. having created a prepared-recovery-record, this record should not be deleted until after:
    • a. an ABORT message is received; or
    • b. a COMMIT message is received; or
    • c. a QUERIEDNOTFOUND response is received.
  3. the system should not send a COMMITTED or NOTRECONNECTED message if a prepared-recovery-record exists.
  4. before creating a commit-recovery-record for the transaction, the system should have received a PREPARED response.
  5. before sending a COMMIT message in Prepared state, the system should have created a commit-recovery-record for the transaction.
  6. having created a commit-recovery-record, this record should not be deleted until after:
    • a. a COMMITTED message is received; or
    • b. a NOTRECONNECTED message is received.

11. Security Considerations ๐Ÿ”

okay this section is serious, so buckle up ๐Ÿ˜ญ

the way applications talk to each other and actually do their distributed work? that's totally outside the scope of TIP ๐Ÿ™…โ€โ™€๏ธ the auth and authorisation stuff for clients getting into programs and info on a system lives in the application communications protocol and the app execution infrastructure. using TIP doesn't change any of that, periodt ๐Ÿ’…

security does touch TIP itself, though. systems need to protect themselves from getting unauthorised TIP commands, or from someone impersonating a trusted partner TIP TM ๐Ÿ‘€ the absolute worst case is undetected data inconsistency from messing with the TIP commitment protocol. picture a COMMIT command getting injected on a TIP connection in place of an ABORT command ๐Ÿ’€

so TIP uses the Transport Layer Security protocol [6] to do a few things. it restricts access to only trusted partners, meaning it controls which remote endpoints TIP transactions will be accepted from, and it verifies that an end-point is genuine. it also encrypts TIP commands ๐Ÿ”’ whether TLS gets used at all is negotiated between partner TIP TMs. for the details on how TLS works with TIP, see [1] โœจ

one more thing: TIP TM implementations will likely also offer local ways to time-out and abort transactions that haven't finished within some time period. that helps stop resources from getting tied up due to malicious intent ๐Ÿ›ก๏ธ and transaction time-out doubles as a way to resolve deadlocks ๐Ÿ”“


12. TIP Requirements ๐Ÿ“‹

okay so most of these requirements come from one big goal: making transactions a ubiquitous system service that every application class can use ๐ŸŒธ (kind of like how TCP is just assumed to be everywhere). that means keeping restrictions on TIP use as low as possible. apps shouldn't need to live in some "special" environment just to use transactions ๐Ÿ™…โ€โ™€๏ธ it also means keeping the protocol simple and efficient. that's what makes TIP cheap to implement and cheap to run, so it can show up on a wide range of systems ๐Ÿฆ‹

1) Application Communications Protocol Independence ๐Ÿงฉ

The TIP protocol must be defined independently of the communications protocol used for transferring application data. that way TIP can be used alongside any application protocol. it must be possible for applications using arbitrary communications protocols to begin, end, and propagate TIP transactions โœจ

this implies that the TIP protocol employs a 2-pipe model of operation. the model splits application communications and transaction coordination into two separate communication channels, called pipes. that split is what lets the transaction coordination protocol (TIP) work with any application communications protocol, like HTTP, ODBC, plain TCP/UDP, and so on ๐ŸŒˆ

2) Support for Transaction Semantics ๐Ÿ‘‘

The TIP protocol must provide the functionality of the de-facto standard presumed-abort 2-pc protocol, so transactional atomicity is guaranteed even when failures happen ๐Ÿ’ช it should also provide a way to construct the transaction tree, plus commitment and recovery functions ๐ŸŒณ

3) Application Transaction Propagation and Interoperability ๐Ÿซถ

to make protocol independence and application interoperability happen, and to give TIP a way to propagate transaction context, there needs to be a standard representation of the TIP transaction context information. it's required to be in the form of a URL ๐Ÿ”— that info must include the listening endpoint address of the partner TIP TM, plus transaction identifier information.

4) Ease of Implementation ๐Ÿง

The TIP protocol must be simple to implement. it should only support the features needed to provide a useful, performant 2-pc protocol service. the protocol should not add complexity in the form of extraneous optimisations ๐Ÿ™…โ€โ™€๏ธ

5) Suitability for All Application Classes ๐ŸŒŸ

The TIP protocol should be complete and robust enough not just for electronic commerce on the web, but also for intranet applications and for traditional TP applications spanning heterogenous transaction manager environments. it should also be performant and scaleable enough for low to very high throughput applications ๐Ÿš€

  • a. the TIP protocol should support the concept of client-only transaction participants. that's super useful for ultra-lightweight implementations on low-end platforms ๐Ÿชถ
  • b. since some clients may be unreliable, TIP must provide support for delegation of transaction coordination to a more reliable (trusted) node ๐Ÿค
  • c. the TIP protocol must scale between 1 and n (> 1) concurrent transactions per TCP connection ๐Ÿงต
  • d. TIP commands should be able to be concatenated (pipelined) ๐Ÿ”
  • e. TIP should be compatible with the X/Open XA interface ๐Ÿ“

6) Security ๐Ÿ”

The TIP protocol must be compatible with existing security mechanisms, potentially including encryption, firewalls, and authorization mechanisms. for example, TLS may be used to authenticate the sender of a TIP command, and to encrypt TIP commands ๐Ÿ›ก๏ธ nothing in the protocol definition should stop TIP from working within any security environment ๐Ÿ’œ

7) TIP Protocol Transport Independence ๐Ÿฆ‹

it would be beneficial to some applications to let the TIP protocol flow over different transport protocols. the perk is that when different transports are used for the application data, the same transport can be used for the TIP 2PC protocol. so TIP must not preclude use with other transport protocols ๐ŸŒŠ

8) Recovery ๐Ÿ”„

recovery semantics need to be defined well enough to avoid ambiguous results in the event of any type of communications transport failure ๐Ÿ™ˆ

9) Extensibility ๐Ÿงš

the TIP protocol should be able to be extended while still staying compatible with previous versions ๐Ÿ’–

References ๐Ÿ“š

  • [1] Lyon, J., Evans, K., and J. Klein, "The Transaction Internet Protocol Version 3.0", RFC 2371, July 1998.
  • [2] Transaction Processing: Concepts and Techniques. Morgan Kaufmann Publishers. (ISBN 1-55860-190-2). J. Gray, A. Reuter.
  • [3] X/Open CAE Specification, April 1995, Distributed Transaction Processing: The TX Specification. (ISBN 1-85912-094-6).
  • [4] X/Open Guide, November 1993, Distributed Transaction Processing: Reference Model Version 2. (ISBN 1-85912-019-9).
  • [5] X/Open CAE Specification, December 1991, Distributed Transaction Processing: The XA Specification. (ISBN 1-872630-24-3).
  • [6] Dierks, T., et. al., "The TLS Protocol Version 1.0", Work in Progress.

Authors' Addresses ๐ŸŽ€

Keith Evans
Tandem Computers Inc, LOC 252-30
5425 Stevens Creek Blvd
Santa Clara, CA 95051-7200, USA

Phone: +1 (408) 285 5314
Fax:   +1 (408) 285 5245
EMail: Keith.Evans@Tandem.Com


Johannes Klein
Tandem Computers Inc.
10555 Ridgeview Court
Cupertino, CA 95014-0789, USA

Phone: +1 (408) 285 0453
Fax:   +1 (408) 285 9818
EMail: Johannes.Klein@Tandem.Com


Jim Lyon
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052-6399, USA

Phone: +1 (206) 936 0867
Fax:   +1 (206) 936 7329
EMail: JimLyon@Microsoft.Com

Comments ๐Ÿ’Œ

Please send comments on this document to the authors at <JimLyon@Microsoft.Com>, <Keith.Evans@Tandem.Com>, <Johannes.Klein@Tandem.Com>, or to the TIP mailing list at <Tip@Tandem.Com>. You can subscribe to the TIP mailing list by sending mail to <Listserv@Lists.Tandem.Com> with the line "subscribe tip <full name>" somewhere in the body of the message ๐Ÿ“จ


Appendix A. An Example TIP Transaction Manager Application Programming Interface. ๐Ÿง

Note that this API is included solely for informational purposes, and is not part of the formal TIP specification. TIP conformant implementations are free to define alternative APIs ๐Ÿซถ

1) tip_open() - establish a connection to a TIP TM. ๐Ÿ”Œ

int tip_open ([out] tip_handle_t *ptiptm)

Parameters:

  • ptiptm [out] Pointer to the TIP TM handle.

Description: tip_open() establishes a connection to a TIP TM. The call returns a handle which identifies the TIP TM. this function must be called before any work can be performed on a TIP transaction โœจ

Return Values:

  • [TIPOK] Connection has been successfully established.
  • [TIPNOTCONNECTED] User has been disconnected from the TIP TM.
  • [TIPNOTCONFIGURED] TIP TM has not been configured.
  • [TIPTRANSIENT] Too many openers; re-try the open.
  • [TIPERROR] An unexpected error occurred.

2) tip_close() - close a connection to a TIP TM. ๐Ÿ‘‹

int tip_close([in] tip_handle_t handle)

Parameters:

  • handle [in] The TIP TM handle.

Description: tip_close() closes a connection to a TIP TM. All outstanding requests associated with that connection will be cancelled ๐Ÿฅ€

Return Values:

  • [TIPOK] Connection has been successfully closed.
  • [TIPINVALIDPARM] Invalid connection handle specified.
  • [TIPERROR] An unexpected error occurred.

Okay bestie, the next few functions are the ones that actually move transactions between nodes, so pay attention ๐Ÿ’…โœจ

3) tip_push() ๐Ÿš€

Synopsis

int tip_push ([in] tip_handle_t TM,
              [in] char *tm_url,
              [in] void *plocal_xid,
              [out] char *pxid_url,
              [in] unsigned int url_length)

Parameters

  • TM [in]: the TIP TM handle ๐ŸŽ€
  • tm_url [in]: pointer to the TIP URL of the remote transaction manager. A TIP URL for a transaction manager takes the form TIP://<host>[:<port>]
  • plocal_xid [in]: pointer to the local transaction identifier. The structure of the transaction identifier is defined by the local transaction manager.
  • pxid_url [out]: pointer to the TIP URL of the associated remote transaction. A TIP URL for a transaction takes the form TIP://<host>[:<port>]/<transaction identifier>
  • url_length [in]: the size in bytes of the buffer for the remote transaction URL.

Description

tip_push() exports (pushes) a local transaction to a remote node. If a local transaction identifier isn't supplied, the caller's current transaction context gets used. The call hands back a TIP URL for the associated remote transaction. The TIP transaction identifier can then be passed on application requests to the remote node (as part of a TIP URL), and the receiving process uses it to do work on behalf of the transaction. It's giving teamwork ๐Ÿซถ

Return Values

  • [TIPOK]: the transaction has been successfully pushed to the remote node ๐ŸŽ‰
  • [TIPINVALIDXID]: an invalid transaction identifier has been provided.
  • [TIPNOCURRENTTX]: the process isn't currently associated with a transaction (and none was supplied).
  • [TIPINVALIDHANDLE]: an invalid connection handle was specified.
  • [TIPNOTPUSHED]: the transaction could not be pushed to the remote node.
  • [TIPNOTCONNECTED]: the caller has been disconnected from the TIP TM.
  • [TIPINVALIDURL]: an invalid endpoint URL was provided.
  • [TIPTRANSIENT]: a transient error occurred; re-try the operation.
  • [TIPTRUNCATED]: the buffer size specified for the TIP transaction identifier is insufficient.
  • [TIPERROR]: an unexpected error occurred ๐Ÿ’€

4) tip_pull() ๐Ÿงฒ

Synopsis

int tip_pull([in] tip_handle_t TM,
             [in] char *pxid_url,
             [out] void *plocal_xid,
             [in] unsigned int xid_length)

Parameters

  • TM [in]: the TIP TM handle.
  • pxid_url [in]: pointer to the TIP URL of the associated remote transaction. A TIP URL for a transaction takes the form TIP://<host>[:<port>]/<transaction identifier>
  • plocal_xid [out]: pointer to the local transaction identifier. The structure of the transaction identifier is defined by the local transaction manager.
  • xid_length [in]: the size in bytes of the buffer for the local transaction identifier.

Description

tip_pull() creates a local transaction and joins it with the TIP transaction, so the caller becomes a subordinate participant in the TIP transaction ๐Ÿฆ‹ The remote TIP TM is identified via the URL (*pxid_url), and the local transaction identifier is returned. If a local transaction has already been created for the TIP transaction identifier that was supplied, then [TIPOK] is returned (along with the local transaction identifier), and no other action is taken. Nothing extra happens, which is honestly so iconic ๐Ÿ‘‘

Return Values

  • [TIPOK]: the local transaction has been successfully created and joined with the TIP transaction โœจ
  • [TIPINVALIDHANDLE]: an invalid connection handle was specified.
  • [TIPTRUNCATED]: the buffer size specified for the local transaction identifier is insufficient.
  • [TIPNOTPULLED]: joining the local transaction with the TIP transaction has failed.
  • [TIPNOTCONNECTED]: the caller has been disconnected from the TIP TM.
  • [TIPINVALIDURL]: an invalid URL has been supplied.
  • [TIPTRANSIENT]: a transient error occurred; retry the operation.
  • [TIPERROR]: an unexpected error occurred.

5) tip_pull_async() ๐ŸŒธ

Synopsis

int tip_pull_async ([in] tip_handle_t TM
                    [in] char *pxid_url,
                    [out] void *plocal_xid,
                    [in] unsigned int xid_length)

Parameters

  • TM [in]: the TIP gateway handle.
  • pxid_url [in]: pointer to the TIP URL of the associated remote transaction. A TIP URL for a transaction takes the form TIP://<host>[:<port>]/<transaction identifier>
  • plocal_xid [out]: pointer to the local transaction identifier. The structure of the transaction identifier is defined by the local transaction manager.
  • xid_length [in]: the size in bytes of the buffer for the local transaction identifier.

Description

tip_pull_async() is the speedy cousin of tip_pull() ๐ŸŽ๏ธ๐Ÿ’จ It creates a local transaction and joins it with the TIP transaction (the caller becomes a subordinate participant), and the remote TIP TM is identified via the URL (*pxid_url). The local transaction identifier is returned. The call comes back immediately after the local transaction has been created, which is before the TIP PULL protocol command is sent. After that, a call to tip_pull_complete() must be issued to check for successful completion of the pull request. Don't skip that step, babe ๐Ÿ™ˆ

Return Values

  • [TIPOK]: the local transaction has been successfully created.
  • [TIPINVALIDHANDLE]: an invalid connection handle was specified.
  • [TIPNOTCONNECTED]: the user has been disconnected from the TIP TM.
  • [TIPINVALIDURL]: an invalid URL has been supplied.
  • [TIPTRANSIENT]: a transient error has occurred; retry the operation.
  • [TIPTRUNCATED]: the buffer size specified for the local transaction identifier is insufficient.
  • [TIPERROR]: an unexpected error occurred.

6) tip_pull_complete() ๐Ÿ”

Synopsis

int tip_pull_complete ([in] tip_handle_t TM,
                       [in] void *plocal_xid)

Parameters

  • TM [in]: the TIP TM handle.
  • plocal_xid [in]: pointer to the local transaction identifier. The structure of the transaction identifier is defined by the local transaction manager.

Description

tip_pull_complete() checks whether a previous call to tip_pull_async() has been successfully completed, i.e. whether the local transaction has been successfully joined with the TIP transaction. The caller supplies the local transaction identifier that was returned by the previous call to tip_pull_async(). Repeated calls to tip_pull_complete() for the same local transaction identifier are idempotent, meaning they keep giving the same answer no matter how many times you ask ๐Ÿซถ

Return Values

  • [TIPOK]: the local transaction has been successfully joined with the TIP transaction ๐ŸŽ€
  • [TIPINVALIDHANDLE]: an invalid connection handle was specified.
  • [TIPINVALIDXID]: an invalid transaction identifier has been provided.
  • [TIPNOTPULLED]: joining the local transaction with the TIP transaction has failed. The local transaction has been aborted.
  • [TIPNOTCONNECTED]: the caller has been disconnected from the TIP TM.
  • [TIPERROR]: an unexpected error occurred.

7) tip_xid_to_url() ๐Ÿ”—

Synopsis

int tip_xid_to_url ([in] tip_handle_t TM,
                    [in] void *plocal_xid,
                    [out] char *pxid_url,
                    [in] unsigned int url_length)

Parameters

  • TM [in]: the TIP TM handle.
  • plocal_xid [in]: pointer to the local transaction identifier. The structure of the transaction identifier is defined by the local transaction manager.
  • pxid_url [out]: pointer to the TIP URL of the local transaction. A TIP URL for a transaction takes the form TIP://<host>[:<port>]/<transaction identifier>
  • url_length [in]: the size in bytes of the buffer for the TIP URL.

Description

tip_xid_to_url() returns a TIP transaction identifier for a local transaction identifier. That TIP transaction identifier can be passed to remote applications so they can do work on the transaction, e.g. to pull the local transaction to the remote node ๐ŸŒˆ If a local transaction identifier isn't supplied, the caller's current transaction context gets used. The constant TIPURLSIZE defines the size of a TIP transaction identifier in bytes. This value is implementation specific, so it can vary between implementations ๐Ÿงš

Return Values

  • [TIPOK]: a TIP transaction identifier has been returned.
  • [TIPNOTCONNECTED]: the caller has been disconnected from the TIP TM.
  • [TIPNOCURRENTTX]: the process isn't currently associated with a transaction (and none was supplied).
  • [TIPINVALIDXID]: an invalid local transaction identifier has been supplied.
  • [TIPTRUNCATED]: the buffer size specified for the TIP transaction identifier is insufficient.
  • [TIPERROR]: an unexpected error occurred.
  1. tip_url_to_xid() ๐Ÿฆ‹ - return a local transaction identifier for a TIP transaction identifier.

Synopsis ๐Ÿ“

int tip_url_to_xid ([in] tip_handle_t TM,
                  [in] char *pxid_url,
                  [out] void *plocal_xid,
                  [in] unsigned int xid_length)

Parameters ๐Ÿ’…

  • TM [in] ๐ŸŒธ the TIP TM handle, bestie.
  • pxid_url [in] ๐Ÿ’– a pointer to the TIP URL of the local transaction. A TIP URL for a transaction takes the form:
TIP://<host>[:<port>]/<transaction identifier>
  • plocal_xid [out] โœจ a pointer to the local transaction identifier. The structure of the transaction identifier is defined by the local transaction manager, so that's their call ๐Ÿซถ
  • xid_length [in] ๐Ÿงš the size in bytes of the buffer for the local transaction identifier.

Description ๐Ÿ’œ

tip_url_to_xid() returns a local transaction identifier for a TIP transaction identifier. Quick heads up, though: the local transaction must have previously been created via a tip_push(), or tip_pull (or tip_pull_async()). The constant TIPXIDSIZE defines the size of a local transaction identifier in bytes, and this value is implementation specific ๐Ÿ“

Return Values ๐Ÿ‘‘

  • [TIPOK] ๐ŸŽ€ the local transaction identifier is returned, yay!
  • [TIPINVALIDURL] ๐Ÿ™ˆ you gave it an invalid TIP transaction identifier. Oof.
  • [TIPTRUNCATED] ๐Ÿฅบ the buffer size you specified is too small for the local transaction identifier.
  • [TIPERROR] ๐Ÿ’€ something unexpected went wrong.
  1. tip_get_tm_url() ๐ŸŒˆ - get the name of the local TIP transaction manager in TIP URL form.

Synopsis ๐Ÿ“

int tip_get_tm_url ([in] tip_handle_t TM,
                    [out] char *tm_url,
                    [in] int tm_len);

Parameters ๐Ÿ’…

  • TM[in] ๐ŸŒธ the TIP TM handle.
  • tm_url [in] ๐Ÿฆ‹ a pointer to the TIP URL of the local transaction manager. A TIP URL for a transaction manager takes the form:
TIP://<host>[:<port>]
  • tm_len [out] โœจ the size in bytes of the buffer for the TIP URL of the local transaction manager.

Description ๐Ÿ’œ

tip_get_tm_url() gets the name of the local transaction manager in TIP URL form, which is TIP://<host>[:<port>]. Easy peasy ๐Ÿงš

Return Values ๐Ÿ‘‘

  • [TIPOK] ๐ŸŽ‰ the name of the local transaction manager was successfully returned!
  • [TIPTRUNCATED] ๐Ÿฅบ the name got cut off because the buffer was too small. Retry the operation with a larger buffer size, periodt ๐Ÿ’…

Copyright (C) The Internet Society (1998). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

๐Ÿ“ฆ where this page comes from