📄 build.so
字号:
m4_comment([$Id: build.so,v 10.11 2003/10/18 19:16:21 bostic Exp $])m4_ref_title(Distributed Transactions, Building a Global Transaction Manager, [Transaction Manager], xa/intro, xa/xa_intro)m4_p([dnlManaging distributed transactions and using the two-phase commitprotocol of m4_db from an application requires the application providethe functionality of a global transaction manager (GTM). The GTM isresponsible for the following:])m4_bulletbeginm4_bullet([dnlCommunicating with the multiple environments (potentially on separatesystems).])m4_bullet([Managing the global transaction ID name space.])m4_bullet([Maintaining state information about each distributed transaction.])m4_bullet([Recovering from failures of individual environments.])m4_bullet([dnlRecovering the global transaction state after failure of the globaltransaction manager.])m4_bulletendm4_section([Communicating with multiple m4_db environments])m4_p([dnlTwo-phase commit is required if an application wants to transactionprotect m4_db calls across multiple environments. If the environmentsreside on the same machine, the application can communicate with eachenvironment through its own address space with no additional complexity.If the environments reside on separate machines, the application caneither use the m4_db RPC server to manage the remote environments or itmay use its own messaging capability, translating messages on the remotemachine into calls into the m4_db library (including the recoverycalls). For some applications, it might be sufficient to use Tcl'sremote invocation to remote copies of the tclsh utility into which them4_db library has been dynamically loaded.])m4_section([Managing the Global Transaction ID (GID) name space])m4_p([dnlA global transaction is a transaction that spans multiple environments.Each global transaction must have a unique transaction ID. This uniqueID is the global transaction ID (GID). In m4_db, global transactionIDs must be represented with the confines of a m4_ref(DB_XIDDATASIZE)size (currently 128 bytes) array. It is the responsibility of theglobal transaction manager to assign GIDs, guarantee their uniqueness,and manage the mapping of local transactions to GID. That is, for eachGID, the GTM should know which local transactions managers participated.The m4_db logging system or a m4_db table could be used to record thisinformation.])m4_section([Maintaining state for each distributed transaction.])m4_p([dnlIn addition to knowing which local environments participate in eachglobal transaction, the GTM must also know the state of each activeglobal transaction. As soon as a transaction becomes distributed (thatis, a second environment participates), the GTM must record theexistence of the global transaction and all participants (whether thismust reside on stable storage or not depends on the exact configurationof the system). As new environments participate, the GTM must keep thisinformation up to date.])m4_p([dnlWhen the GTM is ready to begin commit processing, it should issuem4_ref(txn_prepare) calls to each participating environment, indicatingthe GID of the global transaction. Once all the participants havesuccessfully prepared, then the GTM must record that the globaltransaction will be committed. This record should go to stablestorage. Once written to stable storage, the GTM can sendm4_ref(txn_commit) requests to each participating environment. Onceall environments have successfully completed the commit, the GTM caneither record the successful commit or can somehow "forget" the globaltransaction.])m4_p([dnlIf nested transactions are used (that is, the m4_arg(parent) parameteris specified to m4_ref(txn_begin)), no m4_ref(txn_prepare) call shouldbe made on behalf of any child transaction. Only the ultimate parentshould even issue a m4_ref(txn_prepare).])m4_p([dnlShould any participant fail to prepare, then the GTM must abort theglobal transaction. The fact that the transaction is going to beaborted should be written to stable storage. Once written, the GTM canthen issue m4_ref(txn_abort) requests to each environment. When allaborts have returned successfully, the GTM can either record thesuccessful abort or "forget" the global transaction.])m4_p([dnlIn summary, for each transaction, the GTM must maintain the following:])m4_bulletbeginm4_bullet([A list of participating environments])m4_bullet([dnlThe current state of each transaction (pre-prepare, preparing,committing, aborting, done)])m4_bulletendm4_section([Recovering from the failure of a single environment])m4_p([dnlIf a single environment fails, there is no need to bring down or recoverother environments (the only exception to this is if all environmentsare managed in the same application address space and there is a riskthe failure of the environment corrupted other environments). Instead,once the failing environment comes back up, it should be recovered (thatis, conventional recovery, via m4_ref(db_recover) or by specifying them4_ref(DB_RECOVER) flag to m4_ref(dbenv_open) should be run). If them4_ref(db_recover) utility is used, then the -e option must bespecified. In this case, the application will almost certainly want tospecify environmental parameters via a DB_CONFIG file in theenvironment's home directory, so that m4_ref(db_recover) can create anappropriately configured environment. If the m4_ref(db_recover) utilityis not used, then m4_ref(DB_PRIVATE) should not be specified, unlessall processing including recovery, calls to m4_ref(txn_recover), andcalls to finish prepared, but not yet complete transactions take placeusing the same database environment handle. The GTM should then issuea m4_ref(txn_recover) call to the environment. This call will returna list of prepared, but not yet committed or aborted transactions. Foreach transaction, the GTM should look up the GID in its local store todetermine if the transaction should commit or abort.])m4_p([dnlIf the GTM is running in a system with multiple GTMs, it is possiblethat some of the transactions returned via m4_ref(txn_recover) do notbelong to the current environment. The GTM should detect this and callm4_ref(txn_discard) on each such transaction handle. Furthermore, itis important to note the environment does not retain information aboutwhich GTM has issued m4_ref(txn_recover) operations. Therefore, eachGTM should issue all its m4_ref(txn_recover) calls, before another GTMissues its calls. If the calls are interleaved, each GTM may not geta complete and consistent set of transactions. The simplest way toenforce this is for each GTM to make sure it can receive all itsoutstanding transactions in a single m4_ref(txn_recover) call. Themaximum number of possible outstanding transactions is roughly themaximum number of active transactions in the environment (which valuecan be obtained using the m4_refT(txn_stat) or the m4_ref(db_stat)utility). To simplify this procedure, the caller should allocate anarray large enough to be certain to hold the list of transactions (forexample, allocate an array able to hold three times the maximum numberof transactions). If that's not possible, callers should check that thearray was not completely filled in when m4_ref(txn_recover) returns.If the array was completely filled in, each transaction should beexplicitly discarded, and the call repeated with a larger array.])m4_p([dnlThe newly recovered environment will forbid any new transactions frombeing started until the prepared but not yet committed/abortedtransactions have been resolved. In the multiple GTM case, this meansthat all GTMs must recover before any GTM can begin issuing new transactions.])m4_p([dnlBecause m4_db flushed both commit and abort records to disk fortwo-phase transaction, once the global transaction has either committedor aborted, no action will be necessary in any environment. If localenvironments are running with the m4_ref(DB_TXN_WRITE_NOSYNC) orm4_ref(DB_TXN_NOSYNC) options (that is, is not writing and/or flushingthe log synchronously at commit time), then it is possible that a commitor abort operation may not have been written in the environment. Inthis case, the GTM must always have a record of completed transactionsto determine if prepared transactions should be committed or aborted.])m4_section([Recovering from GTM failure])m4_p([dnlIf the GTM fails, it must first recover its local state. Assuming theGTM uses m4_db tables to maintain state, it should runm4_ref(db_recover) (or the m4_ref(DB_RECOVER) option tom4_ref(dbenv_open)) upon startup. Once the GTM is back up and running,it needs to review all its outstanding global transactions, that is alltransaction which are recorded, but not yet committed or aborted.])m4_p([dnlAny global transactions which have not yet reached the prepare phaseshould be aborted. If these transactions were on remote systems, theremote systems should eventually time them out and abort them. If thesetransactions are on the local system, we assume they crashed and wereaborted as part of GTM startup.])m4_p([dnlThe GTM must then identify all environments which need to have theirm4_refT(txn_recover)s called. This includes all environments thatparticipated in any transaction that is in the preparing, aborting, orcommitting state. For each environment, the GTM should issue am4_ref(txn_recover) call. Once each environment has responded, the GTMcan determine the fate of each transaction. The correct behavior isdefined depending on the state of the global transaction according tothe table below.])m4_tagbeginm4_tag(preparing, [dnlif all participating environments return the transaction in the preparedbut not yet committed/aborted state, then the GTM should commit thetransaction. If any participating environment fails to return it, thenthe GTM should issue an abort to all environments that did return it.])m4_tag(committing, [dnlthe GTM should send a commit to any environment that returned thistransaction in its list of prepared but not yet committed/abortedtransactions.])m4_tag(aborting, [dnlthe GTM should send an abort to any environment that returned thistransaction in its list of prepared but not yet committed/abortedtransactions.])m4_tagendm4_page_footer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -