|
|
To enable transactions for your environment, you must initialize the transactional subsystem. Note that doing this also initializes the logging subsystem. In addition, you must initialize the memory pool (in-memory cache). Frequently, but not always, you will also initialize the locking subsystem. For example:
Notice in the following example that you create your environment handle using the db_env_create() function before you open the environment:
#include <stdio.h> #include <stdlib.h> #include "db.h" int main(void) { int ret, ret_c; u_int32_t env_flags; DB_ENV *envp; const char *db_home_dir = "/tmp/myEnvironment"; envp = NULL; /* Open the environment */ ret = db_env_create(&envp, 0); if (ret != 0) { fprintf(stderr, "Error creating environment handle: %s\n", db_strerror(ret)); return (EXIT_FAILURE); } env_flags = DB_CREATE | /* Create the environment if it does * not already exist. */ DB_INIT_TXN | /* Initialize transactions */ DB_INIT_LOCK | /* Initialize locking. */ DB_INIT_LOG | /* Initialize logging */ DB_INIT_MPOOL; /* Initialize the in-memory cache. */ ret = envp->open(envp, db_home_dir, env_flags, 0); if (ret != 0) { fprintf(stderr, "Error opening environment: %s\n", db_strerror(ret)); goto err; } err: /* Close the environment */ if (envp != NULL) { ret_c = envp->close(envp, 0); if (ret_c != 0) { fprintf(stderr, "environment close failed: %s\n", db_strerror(ret_c)); ret = ret_c; } } return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }
You then create and open your database(s) as you would for a non-transactional system. The only difference is that you must pass the environment handle to the db_create() function, and you must open the database within a transaction. Typically auto commit is used for this purpose. To do so, pass DB_AUTO_COMMIT to the database open command. Also, make sure you close all your databases before you close your environment. For example:
#include <stdio.h> #include <stdlib.h> #include "db.h" int main(void) { int ret, ret_c; u_int32_t db_flags, env_flags; DB *dbp; DB_ENV *envp; const char *db_home_dir = "/tmp/myEnvironment"; const char *file_name = "mydb.db"; dbp = NULL; envp = NULL; /* Open the environment */ ret = db_env_create(&envp, 0); if (ret != 0) { fprintf(stderr, "Error creating environment handle: %s\n", db_strerror(ret)); return (EXIT_FAILURE); } env_flags = DB_CREATE | /* Create the environment if it does * not already exist. */ DB_INIT_TXN | /* Initialize transactions */ DB_INIT_LOCK | /* Initialize locking. */ DB_INIT_LOG | /* Initialize logging */ DB_INIT_MPOOL; /* Initialize the in-memory cache. */ ret = envp->open(envp, db_home_dir, env_flags, 0); if (ret != 0) { fprintf(stderr, "Error opening environment: %s\n", db_strerror(ret)); goto err; } /* Initialize the DB handle */ ret = db_create(&dbp, envp, 0); if (ret != 0) { envp->err(envp, ret, "Database creation failed"); goto err; } db_flags = DB_CREATE | DB_AUTO_COMMIT; ret = dbp->open(dbp, /* Pointer to the database */ NULL, /* Txn pointer */ file_name, /* File name */ NULL, /* Logical db name */ DB_BTREE, /* Database type (using btree) */ db_flags, /* Open flags */ 0); /* File mode. Using defaults */ if (ret != 0) { envp->err(envp, ret, "Database '%s' open failed", file_name); goto err; } err: /* Close the database */ if (dbp != NULL) { ret_c = dbp->close(dbp, 0); if (ret_c != 0) { envp->err(envp, ret_c, "Database close failed."); ret = ret_c } } /* Close the environment */ if (envp != NULL) { ret_c = envp->close(envp, 0); if (ret_c != 0) { fprintf(stderr, "environment close failed: %s\n", db_strerror(ret_c)); ret = ret_c; } } return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); }
Never close a database that has active transactions. Make sure all transactions are resolved (either committed or aborted) before closing the database.