00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 #endif
00015
00016 #include "db_int.h"
00017 #include "dbinc/txn.h"
00018
00019
00020
00021
00022
00023
00024
00025 int
00026 __txn_failchk(dbenv)
00027 DB_ENV *dbenv;
00028 {
00029 DB_TXN *ktxn, *txn;
00030 DB_TXNMGR *mgr;
00031 DB_TXNREGION *region;
00032 TXN_DETAIL *ktd, *td;
00033 db_threadid_t tid;
00034 int ret;
00035 char buf[DB_THREADID_STRLEN];
00036 pid_t pid;
00037
00038 mgr = dbenv->tx_handle;
00039 region = mgr->reginfo.primary;
00040
00041 retry: TXN_SYSTEM_LOCK(dbenv);
00042
00043 SH_TAILQ_FOREACH(td, ®ion->active_txn, links, __txn_detail) {
00044
00045
00046
00047
00048 if (td->parent != INVALID_ROFF)
00049 continue;
00050
00051
00052
00053
00054 if (td->status == TXN_PREPARED)
00055 continue;
00056
00057
00058 if (dbenv->is_alive(dbenv, td->pid, td->tid))
00059 continue;
00060
00061 if (F_ISSET(td, TXN_DTL_INMEMORY))
00062 return (__db_failed(dbenv,
00063 "Transaction has in memory logs",
00064 td->pid, td->tid));
00065
00066
00067 TXN_SYSTEM_UNLOCK(dbenv);
00068 if ((ret = __os_calloc(dbenv, 1, sizeof(DB_TXN), &txn)) != 0)
00069 return (ret);
00070 __txn_continue(dbenv, txn, td);
00071 F_SET(txn, TXN_MALLOC);
00072 SH_TAILQ_FOREACH(ktd, &td->kids, klinks, __txn_detail) {
00073 if (F_ISSET(ktd, TXN_DTL_INMEMORY))
00074 return (__db_failed(dbenv,
00075 "Transaction has in memory logs",
00076 td->pid, td->tid));
00077 if ((ret =
00078 __os_calloc(dbenv, 1, sizeof(DB_TXN), &ktxn)) != 0)
00079 return (ret);
00080 __txn_continue(dbenv, ktxn, ktd);
00081 F_SET(ktxn, TXN_MALLOC);
00082 ktxn->parent = txn;
00083 TAILQ_INSERT_HEAD(&txn->kids, txn, klinks);
00084 }
00085 TAILQ_INSERT_TAIL(&mgr->txn_chain, txn, links);
00086 pid = td->pid;
00087 tid = td->tid;
00088 (void)dbenv->thread_id_string(dbenv, pid, tid, buf);
00089 __db_msg(dbenv,
00090 "Aborting txn %#lx: %s", (u_long)txn->txnid, buf);
00091 if ((ret = __txn_abort(txn)) != 0)
00092 return (__db_failed(dbenv,
00093 "Transaction abort failed", pid, tid));
00094 goto retry;
00095 }
00096
00097 TXN_SYSTEM_UNLOCK(dbenv);
00098
00099 return (0);
00100 }