You can transaction-protect your cursor operations by specifying a transaction handle at the time that you create your cursor. Beyond that, you do not ever provide a transaction handle directly to a cursor method.
Note that if you transaction-protect a cursor, then you must make sure that the cursor is closed before you either commit or abort the transaction. For example:
#include <stdio.h>
#include <stdlib.h>
#include "db.h"
int
main(void)
{
DBT key, data;
DBC *cursorp;
DB_TXN *txn = NULL;
int ret, c_ret;
char *replacementString = "new string";
...
/* environment and db handle creation omitted */
...
/* Get the txn handle */
txn = NULL;
ret = envp->txn_begin(envp, NULL, &txn, 0);
if (ret != 0) {
envp->err(envp, ret, "Transaction begin failed.");
goto err;
}
/* Get the cursor, supply the txn handle at that time */
ret = dbp->cursor(dbp, txn, &cursorp, 0);
if (ret != 0) {
envp->err(envp, ret, "Cursor open failed.");
txn->abort(txn);
goto err;
}
/*
* Now use the cursor. Note that we do not supply any txn handles to these
* methods.
*/
/* Prepare the DBTs */
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
while (cursor->c_get(&key, &data, DB_NEXT) == 0) {
data->data = (void *)replacementString;
data->size = (strlen(replacementString) + 1) * sizeof(char);
c_ret = cursor->c_put(cursor, &key, &data, DB_CURRENT);
if (c_ret != 0) {
/* abort the transaction and goto error */
envp->err(envp, ret, "Cursor put failed.");
cursorp->c_close(cursorp);
cursorp = NULL;
txn->abort(txn);
goto err;
}
}
/*
* Commit the transaction. Note that the transaction handle
* can no longer be used.
*/
ret = cursorp->c_close(cursorp);
if (ret != 0) {
envp->err(envp, ret, "Cursor close failed.");
txn->abort(txn);
goto err;
}
ret = txn->commit(txn, 0);
if (ret != 0) {
envp->err(envp, ret, "Transaction commit failed.");
goto err;
}
err:
/* Close the cursor (if the handle is not NULL)
* and perform whatever other cleanup is required */
/* Close the database */
/* Close the environment */
...
if (c_ret != 0)
ret = c_ret;
return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}