📄 xa.c
字号:
return (XA_RBDEADLOCK); if (td->xa_status == TXN_XA_ABORTED) return (XA_RBOTHER); /* Now, fill in the global transaction structure. */ if (__xa_get_txn(dbenv, &txnp, 1) != 0) return (XAER_RMERR); __txn_continue(dbenv, txnp, td, off); td->xa_status = TXN_XA_STARTED; } else { if (__xa_get_txn(dbenv, &txnp, 1) != 0) return (XAER_RMERR); if (__txn_xa_begin(dbenv, txnp)) return (XAER_RMERR); (void)__db_map_xid(dbenv, xid, txnp->off); td = R_ADDR( &((DB_TXNMGR *)dbenv->tx_handle)->reginfo, txnp->off); td->xa_status = TXN_XA_STARTED; } return (XA_OK);}/* * __db_xa_end -- * Disassociate the current transaction from the current process. */static int__db_xa_end(xid, rmid, flags) XID *xid; int rmid; long flags;{ DB_ENV *dbenv; DB_TXN *txn; TXN_DETAIL *td; roff_t off; if (flags != TMNOFLAGS && !LF_ISSET(TMSUSPEND | TMSUCCESS | TMFAIL)) return (XAER_INVAL); if (__db_rmid_to_env(rmid, &dbenv) != 0) return (XAER_PROTO); if (__db_xid_to_txn(dbenv, xid, &off) != 0) return (XAER_NOTA); if (__xa_get_txn(dbenv, &txn, 0) != 0) return (XAER_RMERR); if (off != txn->off) return (XAER_PROTO); td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); if (td->xa_status == TXN_XA_DEADLOCKED) return (XA_RBDEADLOCK); if (td->status == TXN_ABORTED) return (XA_RBOTHER); if (td->xa_status != TXN_XA_STARTED) return (XAER_PROTO); /* Update the shared memory last_lsn field */ td->last_lsn = txn->last_lsn; /* * If we ever support XA migration, we cannot keep SUSPEND/END * status in the shared region; it would have to be process local. */ if (LF_ISSET(TMSUSPEND)) td->xa_status = TXN_XA_SUSPENDED; else td->xa_status = TXN_XA_ENDED; __xa_put_txn(dbenv, txn); return (XA_OK);}/* * __db_xa_prepare -- * Sync the log to disk so we can guarantee recoverability. */static int__db_xa_prepare(xid, rmid, arg_flags) XID *xid; int rmid; long arg_flags;{ DB_ENV *dbenv; DB_TXN *txnp; TXN_DETAIL *td; roff_t off; u_long flags; flags = (u_long)arg_flags; /* Conversion for bit operations. */ if (LF_ISSET(TMASYNC)) return (XAER_ASYNC); if (flags != TMNOFLAGS) return (XAER_INVAL); /* * We need to know if we've ever called prepare on this. * As part of the prepare, we set the xa_status field to * reflect that fact that prepare has been called, and if * it's ever called again, it's an error. */ if (__db_rmid_to_env(rmid, &dbenv) != 0) return (XAER_PROTO); if (__db_xid_to_txn(dbenv, xid, &off) != 0) return (XAER_NOTA); td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); if (td->xa_status == TXN_XA_DEADLOCKED) return (XA_RBDEADLOCK); if (td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED) return (XAER_PROTO); /* Now, fill in the global transaction structure. */ if (__xa_get_txn(dbenv, &txnp, 0) != 0) return (XAER_PROTO); __txn_continue(dbenv, txnp, td, off); if (txnp->prepare(txnp, (u_int8_t *)xid->data) != 0) return (XAER_RMERR); td->xa_status = TXN_XA_PREPARED; /* No fatal value that would require an XAER_RMFAIL. */ __xa_put_txn(dbenv, txnp); return (XA_OK);}/* * __db_xa_commit -- * Commit the transaction */static int__db_xa_commit(xid, rmid, arg_flags) XID *xid; int rmid; long arg_flags;{ DB_ENV *dbenv; DB_TXN *txnp; TXN_DETAIL *td; roff_t off; u_long flags; flags = (u_long)arg_flags; /* Conversion for bit operations. */ if (LF_ISSET(TMASYNC)) return (XAER_ASYNC);#undef OK_FLAGS#define OK_FLAGS (TMNOFLAGS | TMNOWAIT | TMONEPHASE) if (LF_ISSET(~OK_FLAGS)) return (XAER_INVAL); /* * We need to know if we've ever called prepare on this. * We can verify this by examining the xa_status field. */ if (__db_rmid_to_env(rmid, &dbenv) != 0) return (XAER_PROTO); if (__db_xid_to_txn(dbenv, xid, &off) != 0) return (XAER_NOTA); td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); if (td->xa_status == TXN_XA_DEADLOCKED) return (XA_RBDEADLOCK); if (td->xa_status == TXN_XA_ABORTED) return (XA_RBOTHER); if (LF_ISSET(TMONEPHASE) && td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED) return (XAER_PROTO); if (!LF_ISSET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED) return (XAER_PROTO); /* Now, fill in the global transaction structure. */ if (__xa_get_txn(dbenv, &txnp, 0) != 0) return (XAER_RMERR); __txn_continue(dbenv, txnp, td, off); if (txnp->commit(txnp, 0) != 0) return (XAER_RMERR); /* No fatal value that would require an XAER_RMFAIL. */ __xa_put_txn(dbenv, txnp); return (XA_OK);}/* * __db_xa_recover -- * Returns a list of prepared and heuristically completed transactions. * * The return value is the number of xids placed into the xid array (less * than or equal to the count parameter). The flags are going to indicate * whether we are starting a scan or continuing one. */static int__db_xa_recover(xids, count, rmid, flags) XID *xids; long count, flags; int rmid;{ DB_ENV *dbenv; u_int32_t newflags; long rval; /* If the environment is closed, then we're done. */ if (__db_rmid_to_env(rmid, &dbenv) != 0) return (XAER_PROTO); if (LF_ISSET(TMSTARTRSCAN)) newflags = DB_FIRST; else if (LF_ISSET(TMENDRSCAN)) newflags = DB_LAST; else newflags = DB_NEXT; rval = 0; if (__txn_get_prepared(dbenv, xids, NULL, count, &rval, newflags) != 0) return (XAER_RMERR); else return (rval);}/* * __db_xa_rollback * Abort an XA transaction. */static int__db_xa_rollback(xid, rmid, arg_flags) XID *xid; int rmid; long arg_flags;{ DB_ENV *dbenv; DB_TXN *txnp; TXN_DETAIL *td; roff_t off; u_long flags; flags = (u_long)arg_flags; /* Conversion for bit operations. */ if (LF_ISSET(TMASYNC)) return (XAER_ASYNC); if (flags != TMNOFLAGS) return (XAER_INVAL); if (__db_rmid_to_env(rmid, &dbenv) != 0) return (XAER_PROTO); if (__db_xid_to_txn(dbenv, xid, &off) != 0) return (XAER_NOTA); td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); if (td->xa_status == TXN_XA_DEADLOCKED) return (XA_RBDEADLOCK); if (td->xa_status == TXN_XA_ABORTED) return (XA_RBOTHER); if (td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED && td->xa_status != TXN_XA_PREPARED) return (XAER_PROTO); /* Now, fill in the global transaction structure. */ if (__xa_get_txn(dbenv, &txnp, 0) != 0) return (XAER_RMERR); __txn_continue(dbenv, txnp, td, off); if (txnp->abort(txnp) != 0) return (XAER_RMERR); /* No fatal value that would require an XAER_RMFAIL. */ __xa_put_txn(dbenv, txnp); return (XA_OK);}/* * __db_xa_forget -- * Forget about an XID for a transaction that was heuristically * completed. Since we do not heuristically complete anything, I * don't think we have to do anything here, but we should make sure * that we reclaim the slots in the txnid table. */static int__db_xa_forget(xid, rmid, arg_flags) XID *xid; int rmid; long arg_flags;{ DB_ENV *dbenv; roff_t off; u_long flags; flags = (u_long)arg_flags; /* Conversion for bit operations. */ if (LF_ISSET(TMASYNC)) return (XAER_ASYNC); if (flags != TMNOFLAGS) return (XAER_INVAL); if (__db_rmid_to_env(rmid, &dbenv) != 0) return (XAER_PROTO); /* * If mapping is gone, then we're done. */ if (__db_xid_to_txn(dbenv, xid, &off) != 0) return (XA_OK); __db_unmap_xid(dbenv, xid, off); /* No fatal value that would require an XAER_RMFAIL. */ return (XA_OK);}/* * __db_xa_complete -- * Used to wait for asynchronous operations to complete. Since we're * not doing asynch, this is an invalid operation. */static int__db_xa_complete(handle, retval, rmid, flags) int *handle, *retval, rmid; long flags;{ COMPQUIET(handle, NULL); COMPQUIET(retval, NULL); COMPQUIET(rmid, 0); COMPQUIET(flags, 0); return (XAER_INVAL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -