| Access Method | +Description | +
|---|---|
| BTree | +Data is stored in a sorted, balanced tree structure. Both the key and the data for BTree records can be arbitrarily complex. That is, they can contain single values such as an integer or a string, or complex types such as a structure. Also, although not the default behavior, it is possible for two records to use keys that compare as equals. When this occurs, the records are considered to be duplicates of one another. |
+
| Hash | +Data is stored in an extended linear hash table. Like BTree, the key and the data used for Hash records can be of arbitrarily complex data. Also, like BTree, duplicate records are optionally supported. |
+
| Queue | +Data is stored in a queue as fixed-length records. Each record uses a logical record number as its key. This access method is designed for fast inserts at the tail of the queue, and it has a special operation that deletes and returns a record from the head of the queue. +This access method is unusual in that it provides record level locking. This can provide beneficial performance improvements in applications requiring concurrent access to the queue. |
+
| Recno | +Data is stored in either fixed or variable-length records. Like Queue, Recno records use logical record numbers as keys. |
+
DB_CREATE flag on the `open()` method.
+
+The following code fragment illustrates a database open:
+
+``` c
+#include | Access Method | +Description | +
|---|---|
| BTree | +Data is stored in a sorted, balanced tree structure. Both the key and the data for BTree records can be arbitrarily complex. That is, they can contain single values such as an integer or a string, or complex types such as a structure. Also, although not the default behavior, it is possible for two records to use keys that compare as equals. When this occurs, the records are considered to be duplicates of one another. |
+
| Hash | +Data is stored in an extended linear hash table. Like BTree, the key and the data used for Hash records can be of arbitrarily complex data. Also, like BTree, duplicate records are optionally supported. |
+
| Queue | +Data is stored in a queue as fixed-length records. Each record uses a logical record number as its key. This access method is designed for fast inserts at the tail of the queue, and it has a special operation that deletes and returns a record from the head of the queue. +This access method is unusual in that it provides record level locking. This can provide beneficial performance improvements in applications requiring concurrent access to the queue. |
+
| Recno | +Data is stored in either fixed or variable-length records. Like Queue, Recno records use logical record numbers as keys. |
+
| Flag | +Description | +
|---|---|
DB_REP_MASTER |
+The application starts up and declares the environment to be a master without calling for an election. It is an error for more than one environment to start up using this flag, or for an environment to use this flag when a master already exists. +Note that no replication group should ever operate with more than one master. +In the event that a environment attempts to become a master when a master already exists, the replication code will resolve the problem by holding an election. Note, however, that there is always a possibility of data loss in the face of duplicate masters, because once a master is selected, the environment that loses the election will have to roll back any transactions committed until it is in sync with the "real" master. |
+
DB_REP_CLIENT |
+The application starts up and declares the environment to be a replica without calling for an election. Note that the environment can still become a master if a subsequent application starts up, calls for an election, and this environment is elected master. |
+
DB_REP_ELECTION |
+As described above, the application starts up, looks for a master, and if one is not found calls for an election. |
+
| Option | +Description | +
|---|---|
ReplicationManagerStartPolicy. REP_MASTER |
+The application starts up and declares the environment to be a master without calling for an election. It is an error for more than one environment to start up using this flag, or for an environment to use this flag when a master already exists. +Note that no replication group should ever operate with more than one master. +In the event that a environment attempts to become a master when a master already exists, the replication code will resolve the problem by holding an election. Note, however, that there is always a possibility of data loss in the face of duplicate masters, because once a master is selected, the environment that loses the election will have to roll back any transactions committed until it is in sync with the "real" master. |
+
ReplicationManagerStartPolicy. REP_CLIENT |
+The application starts up and declares the environment to be a replica without calling for an election. Note that the environment can still become a master if a subsequent application starts up, calls for an election, and this environment is elected master. |
+
ReplicationManagerStartPolicy. REP_ELECTION |
+As described above, the application starts up, looks for a master, and if one is not found calls for an election. |
+
| File Type | +To Override | +
|---|---|
| database files | +You can cause database files to be created in a directory other than the environment home by using the This method modifies the directory used for database files created and managed by a single environment handle; it does not configure the entire environment. This method may not be called after the environment has been opened. +You can also set a default data location that is used by the entire environment by using the |
+
| Log files | +You can cause log files to be created in a directory other than the environment home directory by using the This method modifies the directory used for database files created and managed by a single environment handle; it does not configure the entire environment. This method may not be called after the environment has been opened. +You can also set a default log file location that is used by the entire environment by using the |
+
| Temporary files | +You can cause temporary files required by the environment to be created in a directory other than the environment home directory by using the You can also set a temporary file location by using the |
+
| Metadata files | +You can cause persistent metadata files required by the replicated applications to be created in a directory other than the environment home directory by using the You can also set a metadata directory location by using the |
+
| Region files | +If backed by the filesystem, region files are always placed in the environment home directory. | +
| Degree | +ANSI Term | +Definition | +
|---|---|---|
| 1 | +READ UNCOMMITTED | +Uncommitted reads means that one transaction will never overwrite another transaction's dirty data. Dirty data is data that a transaction has modified but not yet committed to the underlying data store. However, uncommitted reads allows a transaction to see data dirtied by another transaction. In addition, a transaction may read data dirtied by another transaction, but which subsequently is aborted by that other transaction. In this latter case, the reading transaction may be reading data that never really existed in the database. | +
| 2 | +READ COMMITTED | +Committed read isolation means that degree 1 is observed, except that dirty data is never read. +In addition, this isolation level guarantees that data will never change so long as it is addressed by the cursor, but the data may change before the reading cursor is closed. In the case of a transaction, data at the current cursor position will not change, but once the cursor moves, the previous referenced data can change. This means that readers release read locks before the cursor is closed, and therefore, before the transaction completes. Note that this level of isolation causes the cursor to operate in exactly the same way as it does in the absence of a transaction. |
+
| 3 | +SERIALIZABLE | +Committed read is observed, plus the data read by a transaction, T, will never be dirtied by another transaction before T completes. This means that both read and write locks are not released until the transaction completes. +In addition, no transactions will see phantoms. Phantoms are records returned as a result of a search, but which were not seen by the same transaction when the identical search criteria was previously used. +This is DB's default isolation guarantee. |
+
db_deadlock reference documentation.
+
+### Resolving Deadlocks
+
+When DB determines that a deadlock has occurred, it will select a thread of control to resolve the deadlock and then throws `DbDeadlockException` in that thread. If a deadlock is detected, the thread must:
+
+1. Cease all read and write operations.
+
+2. Close all open cursors.
+
+3. Abort the transaction.
+
+4. Optionally retry the operation. If your application retries deadlocked operations, the new attempt must be made using a new transaction.
+
+### Note
+
+If a thread has deadlocked, it may not make any additional database calls using the handle that has deadlocked.
+
+For example:
+
+``` c
+// retry_count is a counter used to identify how many times
+// we've retried this operation. To avoid the potential for
+// endless looping, we won't retry more than MAX_DEADLOCK_RETRIES
+// times.
+
+// txn is a transaction handle.
+// key and data are DBT handles. Their usage is not shown here.
+while (retry_count < MAX_DEADLOCK_RETRIES) {
+ try {
+ envp->txn_begin(NULL, txn, 0);
+ dbp->put(txn, &key, &data, 0);
+ txn->commit(0);
+ return (EXIT_SUCCESS);
+ } catch (DbDeadlockException &de) {
+ try {
+ // Abort the transaction and increment the
+ // retry counter
+ txn->abort();
+ retry_count++;
+ // If we've retried too many times, log it and exit
+ if (retry_count >= MAX_DEADLOCK_RETRIES) {
+ envp->errx("Exceeded retry limit. Giving up.");
+ return (EXIT_FAILURE);
+ }
+ } catch (DbException &ae) {
+ envp->err(ae.get_errno(), "txn abort failed.");
+ return (EXIT_FAILURE);
+ }
+ } catch (DbException &e) {
+ try {
+ // For a generic error, log it and abort.
+ envp->err(e.get_errno(), "Error putting data.");
+ txn->abort();
+ } catch (DbException &ae) {
+ envp->err(ae.get_errno(), "txn abort failed.");
+ return (EXIT_FAILURE);
+ }
+ }
+}
+```
+
+### Setting Transaction Priorities
+
+Normally when a thread of control must be selected to resolve a deadlock, DB decides which thread will perform the resolution; you have no way of knowing in advance which thread will be selected to resolve the deadlock.
+
+However, there may be situations where you know it is better for one thread to resolve a deadlock over another thread. As an example, if you have a background thread running data management activities, and another thread responding to user requests, you might want deadlock resolution to occur in the background thread because you can better afford the throughput costs there. Under these circumstances, you can identify which thread of control will be selected for resolved deadlocks by setting a transaction priorities.
+
+When two transactions are deadlocked, DB will abort the transaction with the lowest priority. By default, every transaction is given a priority of 100. However, you can set a different priority on a transaction-by-transaction basis by using the `DbTxn::set_priority()` method.
+
+When two or more transactions are tied for the lowest priority, the tie is broken based on the policy provided to the `DbEnv::lock_detect()` method's `atype` parameter.
+
+A transaction's priority can be changed at any time after the transaction handle has been created and before the transaction has been resolved (committed or aborted). For example:
+
+``` c
+#include "db_cxx.h"
+
+...
+
+int main(void)
+{
+ ...
+
+ try {
+
+ ...
+ // Database and environment open omitted for brevity.
+ ...
+ DbTxn *txn = NULL;
+ myEnv.txn_begin(NULL, &txn, 0);
+ txn->set_priority(200);
+
+ try {
+ db->put(txn, &key, &data, 0);
+ txn->commit(0);
+ } catch (DbException &e) {
+ std::cerr << "Error in transaction: "
+ << e.what() << std::endl;
+ txn->abort();
+ }
+
+ } catch(DbException &e) {
+ std::cerr << "Error opening database and environment: "
+ << file_name << ", "
+ << envHome << std::endl;
+ std::cerr << e.what() << std::endl;
+ }
+
+ ...
+
+}
+```
diff --git a/docs_src/guides/gsg_txn/cxx/logconfig.md b/docs_src/guides/gsg_txn/cxx/logconfig.md
new file mode 100644
index 000000000..74bff1054
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/logconfig.md
@@ -0,0 +1,140 @@
+---
+title: "Configuring the Logging Subsystem"
+api-name: "Configuring the Logging Subsystem"
+source: docs/gsg_txn/CXX/logconfig.html
+---
+## Configuring the Logging Subsystem
+
+ [Setting the Log File Size](logconfig.md#logfilesize)
+
+ [Configuring the Logging Region Size](logconfig.md#logregionsize)
+
+ [Configuring In-Memory Logging](logconfig.md#inmemorylogging)
+
+ [Setting the In-Memory Log Buffer Size](logconfig.md#logbuffer)
+
+You can configure the following aspects of the logging subsystem:
+
+- Size of the log files.
+
+- Size of the logging subsystem's region. See Configuring the Logging Region Size.
+
+- Maintain logs entirely in-memory. See Configuring In-Memory Logging for more information.
+
+- Size of the log buffer in memory. See Setting the In-Memory Log Buffer Size.
+
+- On-disk location of your log files. See Identifying Specific File Locations.
+
+### Setting the Log File Size
+
+Whenever a pre-defined amount of data is written to a log file (10 MB by default), DB stops using the current log file and starts writing to a new file. You can change the maximum amount of data contained in each log file by using the `DbEnv::set_lg_max()` method. Note that this method can be used at any time during an application's lifetime.
+
+Setting the log file size to something larger than its default value is largely a matter of convenience and a reflection of the application's preference in backup media and frequency. However, if you set the log file size too low relative to your application's traffic patterns, you can cause yourself trouble.
+
+From a performance perspective, setting the log file size to a low value can cause your active transactions to pause their writing activities more frequently than would occur with larger log file sizes. Whenever a transaction completes the log buffer is flushed to disk. Normally other transactions can continue to write to the log buffer while this flush is in progress. However, when one log file is being closed and another created, all transactions must cease writing to the log buffer until the switch over is completed.
+
+Beyond performance concerns, using smaller log files can cause you to use more physical files on disk. As a result, your application could run out of log sequence numbers, depending on how busy your application is.
+
+Every log file is identified with a 10 digit number. Moreover, the maximum number of log files that your application is allowed to create in its lifetime is 2,000,000,000.
+
+For example, if your application performs 6,000 transactions per second for 24 hours a day, and you are logging 500 bytes of data per transaction into 10 MB log files, then you will run out of log files in around 221 years:
+
+``` c
+ (10 * 2^20 * 2000000000) / (6000 * 500 * 365 * 60 *60 * 24) = 221
+```
+
+However, if you were writing 2000 bytes of data per transaction, and using 1 MB log files, then the same formula shows you running out of log files in 5 years time.
+
+All of these time frames are quite long, to be sure, but if you do run out of log files after, say, 5 years of continuous operations, then you must reset your log sequence numbers. To do so:
+
+1. Backup your databases as if to prepare for catastrophic failure. See Backup Procedures for more information.
+
+2. Reset the log file's sequence number using the **db_load** utility's `-r` option.
+
+3. Remove all of the log files from your environment. Note that this is the only situation in which all of the log files are removed from an environment; in all other cases, at least a single log file is retained.
+
+4. Restart your application.
+
+### Configuring the Logging Region Size
+
+The logging subsystem's default region size is 60 KB. The logging region is used to store filenames, and so you may need to increase its size if a large number of files (that is, if you have a very large number of databases) will be opened and registered with DB's log manager.
+
+You can set the size of your logging region by using the `DbEnv::set_lg_region()` method. Note that this method can only be called before the first environment handle for your application is opened.
+
+### Configuring In-Memory Logging
+
+It is possible to configure your logging subsystem such that logs are maintained entirely in memory. When you do this, you give up your transactional durability guarantee. Without log files, you have no way to run recovery so any system or software failures that you might experience can corrupt your databases.
+
+However, by giving up your durability guarantees, you can greatly improve your application's throughput by avoiding the disk I/O necessary to write logging information to disk. In this case, you still retain your transactional atomicity, consistency, and isolation guarantees.
+
+To configure your logging subsystem to maintain your logs entirely in-memory:
+
+- Make sure your log buffer is capable of holding all log information that can accumulate during the longest running transaction. See Setting the In-Memory Log Buffer Size for details.
+
+- Do not run normal recovery when you open your environment. In this configuration, there are no log files available against which you can run recovery. As a result, if you specify recovery when you open your environment, it is ignored.
+
+- Specify `DB_LOG_IN_MEMORY` to the `DbEnv::log_set_config()` method. Note that you must specify this before your application opens its first environment handle.
+
+For example:
+
+``` c
+#include "db_cxx.h"
+
+...
+
+int main(void)
+{
+ // Set the normal flags for a transactional subsystem. Note that
+ // we DO NOT specify DB_RECOVER.
+ u_int32_t env_flags = DB_CREATE | // If the environment does not
+ // exist, create it.
+ DB_INIT_LOCK | // Initialize locking
+ DB_INIT_LOG | // Initialize logging
+ DB_INIT_MPOOL | // Initialize the cache
+ DB_THREAD | // Free-thread the env handle
+ DB_INIT_TXN; // Initialize transactions
+
+ std::string envHome("/export1/testEnv");
+ DbEnv myEnv(0);
+
+ try {
+
+ // Indicate that logging is to be performed only in memory.
+ // Doing this means that we give up our transactional durability
+ // guarantee.
+ myEnv.log_set_config(DB_LOG_IN_MEMORY, 1);
+
+ // Configure the size of our log memory buffer. This must be
+ // large enough to hold all the logging information likely
+ // to be created for our longest running transaction. The
+ // default size for the logging buffer is 1 MB when logging
+ // is performed in-memory. For this example, we arbitrarily
+ // set the logging buffer to 5 MB.
+ myEnv.set_lg_bsize(5 * 1024 * 1024);
+
+ // Open the environment as normal.
+ myEnv.open(envHome.c_str(), env_flags, 0);
+
+ } catch(DbException &e) {
+ std::cerr << "Error opening database and environment: "
+ << file_name << ", "
+ << envHome << std::endl;
+ std::cerr << e.what() << std::endl;
+ }
+
+ // From here, you open databases, create transactions and
+ // perform database operations exactly as you would if you
+ // were logging to disk. This part is omitted for brevity.
+```
+
+### Setting the In-Memory Log Buffer Size
+
+When your application is configured for on-disk logging (the default behavior for transactional applications), log information is stored in-memory until the storage space fills up, or a transaction commit forces the log information to be flushed to disk.
+
+It is possible to increase the amount of memory available to your file log buffer. Doing so improves throughput for long-running transactions, or for transactions that produce a large amount of data.
+
+When you have your logging subsystem configured to maintain your log entirely in memory (see Configuring In-Memory Logging), it is very important to configure your log buffer size because the log buffer must be capable of holding all log information that can accumulate during the longest running transaction. You must make sure that the in-memory log buffer size is large enough that no transaction will ever span the entire buffer. You must also avoid a state where the in-memory buffer is full and no space can be freed because a transaction that started the first log "file" is still active.
+
+When your logging subsystem is configured for on-disk logging, the default log buffer space is 32 KB. When in-memory logging is configured, the default log buffer space is 1 MB.
+
+You can increase your log buffer space using the `DbEnv::set_lg_bsize()` method. Note that this method can only be called before the first environment handle for your application is opened.
diff --git a/docs_src/guides/gsg_txn/cxx/logfileremoval.md b/docs_src/guides/gsg_txn/cxx/logfileremoval.md
new file mode 100644
index 000000000..b9576bbc1
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/logfileremoval.md
@@ -0,0 +1,42 @@
+---
+title: "Removing Log Files"
+api-name: "Removing Log Files"
+source: docs/gsg_txn/CXX/logfileremoval.html
+---
+## Removing Log Files
+
+By default DB does not delete log files for you. For this reason, DB's log files will eventually grow to consume an unnecessarily large amount of disk space. To guard against this, you should periodically take administrative action to remove log files that are no longer in use by your application.
+
+You can remove a log file if all of the following are true:
+
+- the log file is not involved in an active transaction.
+
+- a checkpoint has been performed *after* the log file was created.
+
+- the log file is not the only log file in the environment.
+
+- the log file that you want to remove has already been included in an offline or hot backup. Failure to observe this last condition can cause your backups to be unusable.
+
+DB provides several mechanisms to remove log files that meet all but the last criteria (DB has no way to know which log files have already been included in a backup). The following mechanisms make it easy to remove unneeded log files, but can result in an unusable backup if the log files are not first saved to your archive location. All of the following mechanisms automatically delete unneeded log files for you:
+
+- Run the **db_archive** command line utility with the `-d` option.
+
+- From within your application, call the `DbEnv::log_archive()` method with the `DB_ARCH_REMOVE` flag.
+
+- Call `DbEnv::log_set_config()` method with the `DB_LOG_AUTO_REMOVE` flag. Note that this flag can be set at any point in the lifetime of your application. Setting this parameter affects all environment handles opened against the environment; not just the handle used to set the flag.
+
+ Note that unlike the other log removal mechanisms identified here, this method actually causes log files to be removed on an on-going basis as they become unnecessary. This is extremely desirable behavior if what you want is to use the absolute minimum amount of disk space possible for your application. This mechanism *will* leave you with the log files that are required to run normal recovery. However, it is highly likely that this mechanism will prevent you from running catastrophic recovery.
+
+ Do NOT use this mechanism if you want to be able to perform catastrophic recovery, or if you want to be able to maintain a hot backup.
+
+In order to safely remove log files and still be able to perform catastrophic recovery, use the **db_archive** command line utility as follows:
+
+1. Run either a normal or hot backup as described in Backup Procedures. Make sure that all of this data is safely stored to your backup media before continuing.
+
+2. If you have not already done so, perform a checkpoint. See Checkpoints for more information.
+
+3. If you are maintaining a hot backup, perform the hot backup procedure as described in Using Hot Failovers.
+
+4. Run the **db_archive** command line utility with the `-d` option against your production environment.
+
+5. Run the **db_archive** command line utility with the `-d` option against your failover environment, if you are maintaining one.
diff --git a/docs_src/guides/gsg_txn/cxx/maxtxns.md b/docs_src/guides/gsg_txn/cxx/maxtxns.md
new file mode 100644
index 000000000..a5b2f831e
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/maxtxns.md
@@ -0,0 +1,70 @@
+---
+title: "Configuring the Transaction Subsystem"
+api-name: "Configuring the Transaction Subsystem"
+source: docs/gsg_txn/CXX/maxtxns.html
+---
+## Configuring the Transaction Subsystem
+
+Most of the configuration activities that you need to perform for your transactional DB application will involve the locking and logging subsystems. See Concurrency and Managing DB Files for details.
+
+However, there are a couple of things that you can do to configure your transaction subsystem directly. These things are:
+
+-
+
+ Configure the maximum number of simultaneous transactions needed by your application. In general, you should not need to do this unless you use deeply nested transactions or you have many threads all of which have active transactions. In addition, you may need to configure a higher maximum number of transactions if you are using snapshot isolation. See Snapshot Isolation Transactional Requirements for details.
+
+ By default, your application can support 20 active transactions.
+
+ You can set the maximum number of simultaneous transactions supported by your application using the `DbEnv::set_tx_max()` method. Note that this method must be called before the environment has been opened.
+
+ If your application has exceeded this maximum value, then any attempt to begin a new transaction will fail.
+
+ This value can also be set using the `DB_CONFIG` file's `set_tx_max` parameter. Remember that the `DB_CONFIG` must reside in your environment home directory.
+
+-
+
+ Configure the timeout value for your transactions. This value represents the longest period of time a transaction can be active. Note, however, that transaction timeouts are checked only when DB examines its lock tables for blocked locks (see Locks, Blocks, and Deadlocks for more information). Therefore, a transaction's timeout can have expired, but the application will not be notified until DB has a reason to examine its lock tables.
+
+ Be aware that some transactions may be inappropriately timed out before the transaction has a chance to complete. You should therefore use this mechanism only if you know your application might have unacceptably long transactions and you want to make sure your application will not stall during their execution. (This might happen if, for example, your transaction blocks or requests too much data.)
+
+ Note that by default transaction timeouts are set to 0 seconds, which means that they never time out.
+
+ To set the maximum timeout value for your transactions, use the `DbEnv::set_timeout()` method. This method configures the entire environment; not just the handle used to set the configuration. Further, this value may be set at any time during the application's lifetime.
+
+ This value can also be set using the `DB_CONFIG` file's `set_txn_timeout` parameter.
+
+For example:
+
+``` c
+#include "db_cxx.h"
+
+...
+
+int main(void)
+{
+ u_int32_t env_flags = DB_CREATE | // If the environment does not
+ // exist, create it.
+ DB_INIT_LOCK | // Initialize locking
+ DB_INIT_LOG | // Initialize logging
+ DB_INIT_MPOOL | // Initialize the cache
+ DB_THREAD | // Free-thread the env handle
+ DB_INIT_TXN; // Initialize transactions
+
+ std::string envHome("/export1/testEnv");
+ DbEnv myEnv(0);
+
+ try {
+
+ // Configure a maximum transaction timeout of 1 second.
+ myEnv.set_timeout(1000000, DB_SET_TXN_TIMEOUT);
+ // Configure 40 maximum transactions.
+ myEnv.set_tx_max(40);
+ myEnv.open(envHome.c_str(), env_flags, 0);
+
+ // From here, you open your databases, proceed with your
+ // database operations, and respond to deadlocks as
+ // is normal (omitted for brevity).
+
+
+ ...
+```
diff --git a/docs_src/guides/gsg_txn/cxx/moreinfo.md b/docs_src/guides/gsg_txn/cxx/moreinfo.md
new file mode 100644
index 000000000..a4947bfc0
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/moreinfo.md
@@ -0,0 +1,28 @@
+---
+title: "For More Information"
+api-name: "For More Information"
+source: docs/gsg_txn/CXX/moreinfo.html
+---
+## For More Information
+
+ [Contact Us](moreinfo.md#contact_us)
+
+Beyond this manual, you may also find the following sources of information useful when building a transactional DB application:
+
+- Getting Started with Berkeley DB for C++
+
+- Berkeley DB Getting Started with Replicated Applications for C++
+
+- Berkeley DB Programmer's Reference Guide
+
+- Berkeley DB C++ API Reference Guide
+
+To download the latest Berkeley DB documentation along with white papers and other collateral, visit http://www.oracle.com/technetwork/indexes/documentation/index.html.
+
+For the latest version of the Oracle Berkeley DB downloads, visit http://www.oracle.com/technetwork/database/berkeleydb/downloads/index.html.
+
+### Contact Us
+
+You can post your comments and questions at the Oracle Technology (OTN) forum for Oracle Berkeley DB at: http://forums.oracle.com/forums/forum.jspa?forumID=271, or for Oracle Berkeley DB High Availability at: http://forums.oracle.com/forums/forum.jspa?forumID=272.
+
+For sales or support information, email to: berkeleydb-info_us@oracle.com You can subscribe to a low-volume email announcement list for the Berkeley DB product family by sending email to: bdb-join@oss.oracle.com
diff --git a/docs_src/guides/gsg_txn/cxx/multithread-intro.md b/docs_src/guides/gsg_txn/cxx/multithread-intro.md
new file mode 100644
index 000000000..025c10ed4
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/multithread-intro.md
@@ -0,0 +1,14 @@
+---
+title: "Multi-threaded and Multi-process Applications"
+api-name: "Multi-threaded and Multi-process Applications"
+source: docs/gsg_txn/CXX/multithread-intro.html
+---
+## Multi-threaded and Multi-process Applications
+
+DB is designed to support multi-threaded and multi-process applications, but their usage means you must pay careful attention to issues of concurrency. Transactions help your application's concurrency by providing various levels of isolation for your threads of control. In addition, DB provides mechanisms that allow you to detect and respond to deadlocks.
+
+*Isolation* means that database modifications made by one transaction will not normally be seen by readers from another transaction until the first commits its changes. Different threads use different transaction handles, so this mechanism is normally used to provide isolation between database operations performed by different threads.
+
+Note that DB supports different isolation levels. For example, you can configure your application to see uncommitted reads, which means that one transaction can see data that has been modified but not yet committed by another transaction. Doing this might mean your transaction reads data "dirtied" by another transaction, but which subsequently might change before that other transaction commits its changes. On the other hand, lowering your isolation requirements means that your application can experience improved throughput due to reduced lock contention.
+
+For more information on concurrency, on managing isolation levels, and on deadlock detection, see Concurrency.
diff --git a/docs_src/guides/gsg_txn/cxx/nestedtxn.md b/docs_src/guides/gsg_txn/cxx/nestedtxn.md
new file mode 100644
index 000000000..b188d62a1
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/nestedtxn.md
@@ -0,0 +1,34 @@
+---
+title: "Nested Transactions"
+api-name: "Nested Transactions"
+source: docs/gsg_txn/CXX/nestedtxn.html
+---
+## Nested Transactions
+
+A *nested transaction* is used to provide a transactional guarantee for a subset of operations performed within the scope of a larger transaction. Doing this allows you to commit and abort the subset of operations independently of the larger transaction.
+
+The rules to the usage of a nested transaction are as follows:
+
+- While the nested (child) transaction is active, the parent transaction may not perform any operations other than to commit or abort, or to create more child transactions.
+
+- Committing a nested transaction has no effect on the state of the parent transaction. The parent transaction is still uncommitted. However, the parent transaction can now see any modifications made by the child transaction. Those modifications, of course, are still hidden to all other transactions until the parent also commits.
+
+- Likewise, aborting the nested transaction has no effect on the state of the parent transaction. The only result of the abort is that neither the parent nor any other transactions will see any of the database modifications performed under the protection of the nested transaction.
+
+- If the parent transaction commits or aborts while it has active children, the child transactions are resolved in the same way as the parent. That is, if the parent aborts, then the child transactions abort as well. If the parent commits, then whatever modifications have been performed by the child transactions are also committed.
+
+- The locks held by a nested transaction are not released when that transaction commits. Rather, they are now held by the parent transaction until such a time as that parent commits.
+
+- Any database modifications performed by the nested transaction are not visible outside of the larger encompassing transaction until such a time as that parent transaction is committed.
+
+- The depth of the nesting that you can achieve with nested transaction is limited only by memory.
+
+To create a nested transaction, simply pass the parent transaction's handle when you created the nested transaction's handle. For example:
+
+``` c
+ // parent transaction
+ DbTxn *parentTxn, *childTxn;
+ ret = myEnv.txn_begin(NULL, &parentTxn, 0);
+ // child transaction
+ ret = myEnv.txn_begin(parent_txn, &childTxn, 0);
+```
diff --git a/docs_src/guides/gsg_txn/cxx/nodurabletxn.md b/docs_src/guides/gsg_txn/cxx/nodurabletxn.md
new file mode 100644
index 000000000..d79cd3826
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/nodurabletxn.md
@@ -0,0 +1,28 @@
+---
+title: "Non-Durable Transactions"
+api-name: "Non-Durable Transactions"
+source: docs/gsg_txn/CXX/nodurabletxn.html
+---
+## Non-Durable Transactions
+
+As previously noted, by default transaction commits are durable because they cause the modifications performed under the transaction to be synchronously recorded in your on-disk log files. However, it is possible to use non-durable transactions.
+
+You may want non-durable transactions for performance reasons. For example, you might be using transactions simply for the isolation guarantee. In this case, you might not want a durability guarantee and so you may want to prevent the disk I/O that normally accompanies a transaction commit.
+
+There are several ways to remove the durability guarantee for your transactions:
+
+- Specify `DB_TXN_NOSYNC` using the `DbEnv::set_flags()` method. This causes DB to not synchronously force any log data to disk upon transaction commit. That is, the modifications are held entirely in the in-memory cache and the logging information is not forced to the filesystem for long-term storage. Note, however, that the logging data will eventually make it to the filesystem (assuming no application or OS crashes) as a part of DB's management of its logging buffers and/or cache.
+
+ This form of a commit provides a weak durability guarantee because data loss can occur due to an application or OS crash.
+
+ This behavior is specified on a per-environment handle basis. In order for your application to exhibit consistent behavior, you need to specify this flag for all of the environment handles used in your application.
+
+ You can achieve this behavior on a transaction by transaction basis by specifying `DB_TXN_NOSYNC` to the `DbTxn::commit()` method.
+
+- Specify `DB_TXN_WRITE_NOSYNC` using the `DbEnv::set_flags()` method. This causes logging data to be synchronously written to the OS's file system buffers upon transaction commit. The data will eventually be written to disk, but this occurs when the operating system chooses to schedule the activity; the transaction commit can complete successfully before this disk I/O is performed by the OS.
+
+ This form of commit protects you against application crashes, but not against OS crashes. This method offers less room for the possibility of data loss than does `DB_TXN_NOSYNC`.
+
+ This behavior is specified on a per-environment handle basis. In order for your application to exhibit consistent behavior, you need to specify this flag for all of the environment handles used in your application.
+
+- Maintain your logs entirely in-memory. In this case, your logs are never written to disk. The result is that you lose all durability guarantees. See Configuring In-Memory Logging for more information.
diff --git a/docs_src/guides/gsg_txn/cxx/perftune-intro.md b/docs_src/guides/gsg_txn/cxx/perftune-intro.md
new file mode 100644
index 000000000..4ca02d2d0
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/perftune-intro.md
@@ -0,0 +1,10 @@
+---
+title: "Performance Tuning"
+api-name: "Performance Tuning"
+source: docs/gsg_txn/CXX/perftune-intro.html
+---
+## Performance Tuning
+
+From a performance perspective, the use of transactions is not free. Depending on how you configure them, transaction commits usually require your application to perform disk I/O that a non-transactional application does not perform. Also, for multi-threaded and multi-process applications, the use of transactions can result in increased lock contention due to extra locking requirements driven by transactional isolation guarantees.
+
+There is therefore a performance tuning component to transactional applications that is not applicable for non-transactional applications (although some tuning considerations do exist whether or not your application uses transactions). Where appropriate, these tuning considerations are introduced in the following chapters. However, for a more complete description of them, see the Transaction tuning and Transaction throughput sections of the *Berkeley DB Programmer's Reference Guide*.
diff --git a/docs_src/guides/gsg_txn/cxx/preface.md b/docs_src/guides/gsg_txn/cxx/preface.md
new file mode 100644
index 000000000..6651bc6fc
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/preface.md
@@ -0,0 +1,62 @@
+---
+title: "Preface"
+api-name: "Preface"
+source: docs/gsg_txn/CXX/preface.html
+---
+## Preface
+
+**Table of Contents**
+
+ [Conventions Used in this Book](preface.md#conventions)
+
+ [For More Information](moreinfo.md)
+
+ [Contact Us](moreinfo.md#contact_us)
+
+This document describes how to use transactions with your Berkeley DB applications. It is intended to describe how to transaction protect your application's data. The APIs used to perform this task are described here, as are the environment infrastructure and administrative tasks required by a transactional application. This book also describes multi-threaded and multi-process DB applications and the requirements they have for deadlock detection.
+
+This book describes Berkeley DB 11*g* Release 2, which provides library version 11.2.5.3.
+
+This book is aimed at the software engineer responsible for writing a transactional DB application.
+
+This book assumes that you have already read and understood the concepts contained in the *Getting Started with Berkeley DB* guide.
+
+## Conventions Used in this Book
+
+The following typographical conventions are used within in this manual:
+
+Class names are represented in `monospaced font`, as are `method names`. For example: "`DbEnv::open()` is a `DbEnv` class method."
+
+Variable or non-literal text is presented in *italics*. For example: "Go to your *DB_INSTALL* directory."
+
+Program examples are displayed in a `monospaced font` on a shaded background. For example:
+
+``` c
+typedef struct vendor {
+ char name[MAXFIELD]; // Vendor name
+ char street[MAXFIELD]; // Street name and number
+ char city[MAXFIELD]; // City
+ char state[3]; // Two-digit US state code
+ char zipcode[6]; // US zipcode
+ char phone_number[13]; // Vendor phone number
+} VENDOR;
+```
+
+In some situations, programming examples are updated from one chapter to the next. When this occurs, the new code is presented in **`monospaced bold`** font. For example:
+
+``` c
+typedef struct vendor {
+ char name[MAXFIELD]; // Vendor name
+ char street[MAXFIELD]; // Street name and number
+ char city[MAXFIELD]; // City
+ char state[3]; // Two-digit US state code
+ char zipcode[6]; // US zipcode
+ char phone_number[13]; // Vendor phone number
+ char sales_rep[MAXFIELD]; // Name of sales representative
+ char sales_rep_phone[MAXFIELD]; // Sales rep's phone number
+} VENDOR;
+```
+
+### Note
+
+Finally, notes of special interest are represented using a note block such as this.
diff --git a/docs_src/guides/gsg_txn/cxx/readmodifywrite.md b/docs_src/guides/gsg_txn/cxx/readmodifywrite.md
new file mode 100644
index 000000000..c4f8c851f
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/readmodifywrite.md
@@ -0,0 +1,44 @@
+---
+title: "Read/Modify/Write"
+api-name: "Read/Modify/Write"
+source: docs/gsg_txn/CXX/readmodifywrite.html
+---
+## Read/Modify/Write
+
+If you are retrieving a record from the database for the purpose of modifying or deleting it, you should declare a read-modify-write cycle at the time that you read the record. Doing so causes DB to obtain write locks (instead of a read locks) at the time of the read. This helps to prevent deadlocks by preventing another transaction from acquiring a read lock on the same record while the read-modify-write cycle is in progress.
+
+Note that declaring a read-modify-write cycle may actually increase the amount of blocking that your application sees, because readers immediately obtain write locks and write locks cannot be shared. For this reason, you should use read-modify-write cycles only if you are seeing a large amount of deadlocking occurring in your application.
+
+In order to declare a read/modify/write cycle when you perform a read operation, pass the `DB_RMW` flag to the database or cursor get method.
+
+For example:
+
+``` c
+// Begin the deadlock retry loop as is normal.
+while (retry_count < MAX_DEADLOCK_RETRIES) {
+ try {
+ envp->txn_begin(NULL, txn, 0);
+
+ ...
+ // key and data are DBTs. Their usage is omitted for brevity.
+ ...
+
+ // Read the data. Declare the read/modify/write cycle here
+ dbp->get(txn, &key, &data, DB_RMW);
+
+ ...
+ // Modify the data as is required. (not shown here)
+ ...
+
+ // Put the data. Note that you do not have to provide any
+ // additional flags here due to the read/modify/write
+ // cycle. Simply put the data and perform your deadlock
+ // detection as normal.
+ dbp->put(txn, &key, &data, 0);
+ txn->commit(0);
+ return (EXIT_SUCCESS);
+ } catch (DbDeadlockException &de) {
+ // Deadlock detection and exception handling omitted
+ // for brevity
+ ...
+```
diff --git a/docs_src/guides/gsg_txn/cxx/recovery-intro.md b/docs_src/guides/gsg_txn/cxx/recovery-intro.md
new file mode 100644
index 000000000..ea56b4743
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/recovery-intro.md
@@ -0,0 +1,18 @@
+---
+title: "Recoverability"
+api-name: "Recoverability"
+source: docs/gsg_txn/CXX/recovery-intro.html
+---
+## Recoverability
+
+An important part of DB's transactional guarantees is durability. *Durability* means that once a transaction has been committed, the database modifications performed under its protection will not be lost due to system failure.
+
+In order to provide the transactional durability guarantee, DB uses a write-ahead logging system. Every operation performed on your databases is described in a log before it is performed on your databases. This is done in order to ensure that an operation can be recovered in the event of an untimely application or system failure.
+
+Beyond logging, another important aspect of durability is recoverability. That is, backup and restore. DB supports a normal recovery that runs against a subset of your log files. This is a routine procedure used whenever your environment is first opened upon application startup, and it is intended to ensure that your database is in a consistent state. DB also supports archival backup and recovery in the case of catastrophic failure, such as the loss of a physical disk drive.
+
+This book describes several different backup procedures you can use to protect your on-disk data. These procedures range from simple offline backup strategies to hot failovers. Hot failovers provide not only a backup mechanism, but also a way to recover from a fatal hardware failure.
+
+This book also describes the recovery procedures you should use for each of the backup strategies that you might employ.
+
+For a detailed description of backup and restore procedures, see Managing DB Files.
diff --git a/docs_src/guides/gsg_txn/cxx/recovery.md b/docs_src/guides/gsg_txn/cxx/recovery.md
new file mode 100644
index 000000000..5af5ac38a
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/recovery.md
@@ -0,0 +1,132 @@
+---
+title: "Recovery Procedures"
+api-name: "Recovery Procedures"
+source: docs/gsg_txn/CXX/recovery.html
+---
+## Recovery Procedures
+
+ [Normal Recovery](recovery.md#normalrecovery)
+
+ [Catastrophic Recovery](recovery.md#catastrophicrecovery)
+
+DB supports two types of recovery:
+
+- Normal recovery, which is run when your environment is opened upon application startup, examines only those log records needed to bring the databases to a consistent state since the last checkpoint. Normal recovery starts with any logs used by any transactions active at the time of the last checkpoint, and examines all logs from then to the current logs.
+
+- Catastrophic recovery, which is performed in the same way that normal recovery is except that it examines all available log files. You use catastrophic recovery to restore your databases from a previously created backup.
+
+Of these two, normal recovery should be considered a routine matter; in fact you should run normal recovery whenever you start up your application.
+
+Catastrophic recovery is run whenever you have lost or corrupted your database files and you want to restore from a backup. You also run catastrophic recovery when you create a hot backup (see Using Hot Failovers for more information).
+
+### Normal Recovery
+
+Normal recovery examines the contents of your environment's log files, and uses this information to ensure that your database files are consistent relative to the information contained in the log files.
+
+Normal recovery also recreates your environment's region files. This has the desired effect of clearing any unreleased locks that your application may have held at the time of an unclean application shutdown.
+
+Normal recovery is run only against those log files created since the time of your last checkpoint. For this reason, your recovery time is dependent on how much data has been written since the last checkpoint, and therefore on how much log file information there is to examine. If you run checkpoints infrequently, then normal recovery can take a relatively long time.
+
+### Note
+
+You should run normal recovery every time you perform application startup.
+
+To run normal recovery:
+
+- Make sure all your environment handles are closed.
+
+- Normal recovery *must be* single-threaded.
+
+- Provide the `DB_RECOVER` flag when you open your environment.
+
+You can also run recovery by pausing or shutting down your application and using the **db_recover** command line utility.
+
+For example:
+
+``` c
+#include "db_cxx.h"
+
+...
+
+void *checkpoint_thread(void *);
+
+int main(void)
+{
+ u_int32_t env_flags = DB_CREATE | // If the environment does not
+ // exist, create it.
+ DB_INIT_LOCK | // Initialize locking
+ DB_INIT_LOG | // Initialize logging
+ DB_INIT_MPOOL | // Initialize the cache
+ DB_INIT_TXN | // Initialize transactions
+ DB_THREAD | // Free-thread the env handle
+ DB_RECOVER; // Run normal recovery
+
+ std::string envHome("/export1/testEnv");
+ DbEnv myEnv(0);
+
+ try {
+
+ myEnv.open(envHome.c_str(), env_flags, 0);
+
+ ...
+
+ // All other operations are identical from here. Notice, however,
+ // that we have not created any other threads of control before
+ // recovery is complete. You want to run recovery for
+ // the first thread in your application that opens an environment,
+ // but not for any subsequent threads.
+```
+
+### Catastrophic Recovery
+
+Use catastrophic recovery when you are recovering your databases from a previously created backup. Note that to restore your databases from a previous backup, you should copy the backup to a new environment directory, and then run catastrophic recovery. Failure to do so can lead to the internal database structures being out of sync with your log files.
+
+Catastrophic recovery must be run single-threaded.
+
+To run catastrophic recovery:
+
+- Shutdown all database operations.
+
+- Restore the backup to an empty directory.
+
+- Provide the `DB_RECOVER_FATAL` flag when you open your environment. This environment open must be single-threaded.
+
+You can also run recovery by pausing or shutting down your application and using the **db_recover** command line utility with the the `-c` option.
+
+Note that catastrophic recovery examines every available log file — not just those log files created since the last checkpoint as is the case for normal recovery. For this reason, catastrophic recovery is likely to take longer than does normal recovery.
+
+For example:
+
+``` c
+#include "db_cxx.h"
+
+...
+
+void *checkpoint_thread(void *);
+
+int main(void)
+{
+ u_int32_t env_flags = DB_CREATE | // If the environment does not
+ // exist, create it.
+ DB_INIT_LOCK | // Initialize locking
+ DB_INIT_LOG | // Initialize logging
+ DB_INIT_MPOOL | // Initialize the cache
+ DB_INIT_TXN | // Initialize transactions
+ DB_THREAD | // Free-thread the env handle
+ DB_RECOVER_FATAL; // Run catastrophic recovery
+
+ std::string envHome("/export1/testEnv");
+ DbEnv myEnv(0);
+
+ try {
+
+ myEnv.open(envHome.c_str(), env_flags, 0);
+
+ ...
+
+ // All other operations are identical from here. Notice, however,
+ // that we have not created any other threads of control before
+ // recovery is complete. You want to run recovery for
+ // the first thread in your application that opens an environment,
+ // but not for any subsequent threads.
+```
diff --git a/docs_src/guides/gsg_txn/cxx/reversesplit.md b/docs_src/guides/gsg_txn/cxx/reversesplit.md
new file mode 100644
index 000000000..57f37047a
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/reversesplit.md
@@ -0,0 +1,76 @@
+---
+title: "Reverse BTree Splits"
+api-name: "Reverse BTree Splits"
+source: docs/gsg_txn/CXX/reversesplit.html
+---
+## Reverse BTree Splits
+
+If your application is using the Btree access method, and your application is repeatedly deleting then adding records to your database, then you might be able to reduce lock contention by turning off reverse Btree splits.
+
+As pages are emptied in a database, DB attempts to delete empty pages in order to keep the database as small as possible and minimize search time. Moreover, when a page in the database fills up, DB, of course, adds additional pages to make room for more data.
+
+Adding and deleting pages in the database requires that the writing thread lock the parent page. Consequently, as the number of pages in your database diminishes, your application will see increasingly more lock contention; the maximum level of concurrency in a database of two pages is far smaller than that in a database of 100 pages, because there are fewer pages that can be locked.
+
+Therefore, if you prevent the database from being reduced to a minimum number of pages, you can improve your application's concurrency throughput. Note, however, that you should do so only if your application tends to delete and then add the same data. If this is not the case, then preventing reverse Btree splits can harm your database search time.
+
+To turn off reverse Btree splits, provide the `DB_REVSPLITOFF` flag to the `Db::set_flags()` method.
+
+For example:
+
+``` c
+#include "db_cxx.h"
+
+...
+
+int main(void)
+{
+ u_int32_t env_flags = DB_CREATE | // If the environment does not
+ // exist, create it.
+ DB_INIT_LOCK | // Initialize locking
+ DB_INIT_LOG | // Initialize locking
+ DB_INIT_MPOOL | // Initialize the cache
+ DB_THREAD | // Free-thread the env handle
+ DB_INIT_TXN; // Initialize transactions
+
+ u_int32_t db_flags = DB_CREATE | DB_AUTO_COMMIT;
+ Db *dbp = NULL;
+ const char *file_name = "mydb.db";
+
+ std::string envHome("/export1/testEnv");
+ DbEnv myEnv(0);
+
+ try {
+
+ myEnv.open(envHome.c_str(), env_flags, 0);
+ dbp = new Db(&myEnv, 0);
+
+ // Turn off BTree reverse split.
+ dbp=>set_flags(DB_REVSPLITOFF);
+
+ 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
+
+ } catch(DbException &e) {
+ std::cerr << "Error opening database and environment: "
+ << file_name << ", " << envHome << std::endl;
+ std::cerr << e.what() << std::endl;
+ }
+
+ try {
+ dbp->close(dbp, 0);
+ myEnv.close(0);
+ } catch(DbException &e) {
+ std::cerr << "Error closing database and environment: "
+ << file_name << ", " << envHome << std::endl;
+ std::cerr << e.what() << std::endl;
+ return (EXIT_FAILURE);
+ }
+
+ return (EXIT_SUCCESS);
+}
+```
diff --git a/docs_src/guides/gsg_txn/cxx/sysfailure.md b/docs_src/guides/gsg_txn/cxx/sysfailure.md
new file mode 100644
index 000000000..4148b052d
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/sysfailure.md
@@ -0,0 +1,18 @@
+---
+title: "A Note on System Failure"
+api-name: "A Note on System Failure"
+source: docs/gsg_txn/CXX/sysfailure.html
+---
+## A Note on System Failure
+
+From time to time this manual mentions that transactions protect your data against 'system or application failure.' This is true up to a certain extent. However, not all failures are created equal and no data protection mechanism can protect you against every conceivable way a computing system can find to die.
+
+Generally, when this book talks about protection against failures, it means that transactions offer protection against the likeliest culprits for system and application crashes. So long as your data modifications have been committed to disk, those modifications should persist even if your application or OS subsequently fails. And, even if the application or OS fails in the middle of a transaction commit (or abort), the data on disk should be either in a consistent state, or there should be enough data available to bring your databases into a consistent state (via a recovery procedure, for example). You may, however, lose whatever data you were committing at the time of the failure, but your databases will be otherwise unaffected.
+
+### Note
+
+Be aware that many disks have a disk write cache and on some systems it is enabled by default. This means that a transaction can have committed, and to your application the data may appear to reside on disk, but the data may in fact reside only in the write cache at that time. This means that if the disk write cache is enabled and there is no battery backup for it, data can be lost after an OS crash even when maximum durability mode is in use. For maximum durability, disable the disk write cache or use a disk write cache with a battery backup.
+
+Of course, if your *disk* fails, then the transactional benefits described in this book are only as good as the backups you have taken. By spreading your data and log files across separate disks, you can minimize the risk of data loss due to a disk failure, but even in this case it is possible to conjure a scenario where even this protection is insufficient (a fire in the machine room, for example) and you must go to your backups for protection.
+
+Finally, by following the programming examples shown in this book, you can write your code so as to protect your data in the event that your code crashes. However, no programming API can protect you against logic failures in your own code; transactions cannot protect you from simply writing the wrong thing to your databases.
diff --git a/docs_src/guides/gsg_txn/cxx/txn_ccursor.md b/docs_src/guides/gsg_txn/cxx/txn_ccursor.md
new file mode 100644
index 000000000..3bb3c94b9
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/txn_ccursor.md
@@ -0,0 +1,79 @@
+---
+title: "Transactional Cursors and Concurrent Applications"
+api-name: "Transactional Cursors and Concurrent Applications"
+source: docs/gsg_txn/CXX/txn_ccursor.html
+---
+## Transactional Cursors and Concurrent Applications
+
+ [Using Cursors with Uncommitted Data](txn_ccursor.md#cursordirtyreads)
+
+When you use transactional cursors with a concurrent application, remember that in the event of a deadlock you must make sure that you close your cursor before you abort and retry your transaction.
+
+Also, remember that when you are using the default isolation level, every time your cursor reads a record it locks that record until the encompassing transaction is resolved. This means that walking your database with a transactional cursor increases the chance of lock contention.
+
+For this reason, if you must routinely walk your database with a transactional cursor, consider using a reduced isolation level such as read committed.
+
+### Using Cursors with Uncommitted Data
+
+As described in Reading Uncommitted Data above, it is possible to relax your transaction's isolation level such that it can read data modified but not yet committed by another transaction. You can configure this when you create your transaction handle, and when you do so then all cursors opened inside that transaction will automatically use uncommitted reads.
+
+You can also do this when you create a cursor handle from within a serializable transaction. When you do this, only those cursors configured for uncommitted reads uses uncommitted reads.
+
+Either way, you must first configure your database handle to support uncommitted reads before you can configure your transactions or your cursors to use them.
+
+The following example shows how to configure an individual cursor handle to read uncommitted data from within a serializable (full isolation) transaction. For an example of configuring a transaction to perform uncommitted reads in general, see Reading Uncommitted Data.
+
+``` c
+#include "db_cxx.h"
+
+...
+
+int main(void)
+{
+ u_int32_t env_flags = DB_CREATE | // If the environment does not
+ // exist, create it.
+ DB_INIT_LOCK | // Initialize locking
+ DB_INIT_LOG | // Initialize logging
+ DB_INIT_MPOOL | // Initialize the cache
+ DB_INIT_TXN; // Initialize transactions
+
+ u_int32_t db_flags = DB_CREATE | // Create the db if it does
+ // not exist
+ DB_AUTO_COMMIT | // Enable auto commit
+ DB_READ_UNCOMMITTED; // Enable uncommitted reads
+
+ Db *dbp = NULL;
+ const char *file_name = "mydb.db";
+
+ std::string envHome("/export1/testEnv");
+ DbEnv myEnv(0);
+
+ Dbc *cursorp = NULL;
+
+ try {
+
+ myEnv.open(envHome.c_str(), env_flags, 0);
+ dbp = new Db(&myEnv, 0);
+ dbp->open(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
+
+ DbTxn *txn = NULL;
+ myEnv.txn_begin(NULL, &txn, 0);
+ try {
+ // Get our cursor. Note that we pass the transaction
+ // handle here. Note also that we pass the
+ // DB_READ_UNCOMMITTED flag here so as to cause the
+ // cursor to perform uncommitted reads.
+ db.cursor(txn, &cursorp, DB_READ_UNCOMMITTED);
+
+ // From here, you perform your cursor reads and writes
+ // as normal, committing and aborting the transactions as
+ // is necessary, and testing for deadlock exceptions as
+ // normal (omitted for brevity).
+
+ ...
+```
diff --git a/docs_src/guides/gsg_txn/cxx/txnconcurrency.md b/docs_src/guides/gsg_txn/cxx/txnconcurrency.md
new file mode 100644
index 000000000..72f581be8
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/txnconcurrency.md
@@ -0,0 +1,104 @@
+---
+title: "Chapter 4. Concurrency"
+api-name: "Chapter 4. Concurrency"
+source: docs/gsg_txn/CXX/txnconcurrency.html
+---
+## Chapter 4. Concurrency
+
+**Table of Contents**
+
+ [Which DB Handles are Free-Threaded](txnconcurrency.md#concurrenthandles)
+
+ [Locks, Blocks, and Deadlocks](blocking_deadlocks.md)
+
+ [Locks](blocking_deadlocks.md#locks)
+
+ [Blocks](blocking_deadlocks.md#blocks)
+
+ [Deadlocks](blocking_deadlocks.md#deadlocks)
+
+ [The Locking Subsystem](lockingsubsystem.md)
+
+ [Configuring the Locking Subsystem](lockingsubsystem.md#configuringlock)
+
+ [Configuring Deadlock Detection](lockingsubsystem.md#configdeadlkdetect)
+
+ [Resolving Deadlocks](lockingsubsystem.md#deadlockresolve)
+
+ [Setting Transaction Priorities](lockingsubsystem.md#setpriority)
+
+ [Isolation](isolation.md)
+
+ [Supported Degrees of Isolation](isolation.md#degreesofisolation)
+
+ [Reading Uncommitted Data](isolation.md#dirtyreads)
+
+ [Committed Reads](isolation.md#readcommitted)
+
+ [Using Snapshot Isolation](isolation.md#snapshot_isolation)
+
+ [Transactional Cursors and Concurrent Applications](txn_ccursor.md)
+
+ [Using Cursors with Uncommitted Data](txn_ccursor.md#cursordirtyreads)
+
+ [Exclusive Database Handles](exclusivelock.md)
+
+ [Read/Modify/Write](readmodifywrite.md)
+
+ [No Wait on Blocks](txnnowait.md)
+
+ [Reverse BTree Splits](reversesplit.md)
+
+DB offers a great deal of support for multi-threaded and multi-process applications even when transactions are not in use. Many of DB's handles are thread-safe, or can be made thread-safe by providing the appropriate flag at handle creation time, and DB provides a flexible locking subsystem for managing databases in a concurrent application. Further, DB provides a robust mechanism for detecting and responding to deadlocks . All of these concepts are explored in this chapter.
+
+Before continuing, it is useful to define a few terms that will appear throughout this chapter:
+
+- *Thread of control*
+
+ Refers to a thread that is performing work in your application. Typically, in this book that thread will be performing DB operations.
+
+ Note that this term can also be taken to mean a separate process that is performing work — DB supports multi-process operations on your databases.
+
+ Also, DB is agnostic with regard to the type or style of threads in use in your application. So if you are using multiple threads (as opposed to multiple processes) to perform concurrent database access, you are free to use whatever thread package is best for your platform and application. That said, this manual will use pthreads for its threading examples because those have the best chance of being supported across a large range of platforms.
+
+- *Locking*
+
+ When a thread of control obtains access to a shared resource, it is said to be *locking* that resource. Note that DB supports both exclusive and non-exclusive locks. See Locks for more information.
+
+- *Free-threaded*
+
+ Data structures and objects are free-threaded if they can be shared across threads of control without any explicit locking on the part of the application. Some books, libraries, and programming languages may use the term *thread-safe* for data structures or objects that have this characteristic. The two terms mean the same thing.
+
+ For a description of free-threaded DB objects, see Which DB Handles are Free-Threaded.
+
+- *Blocked*
+
+ When a thread cannot obtain a lock because some other thread already holds a lock on that object, the lock attempt is said to be *blocked*. See Blocks for more information.
+
+- *Deadlock*
+
+ Occurs when two or more threads of control attempt to access conflicting resource in such a way as none of the threads can any longer make further progress.
+
+ For example, if Thread A is blocked waiting for a resource held by Thread B, while at the same time Thread B is blocked waiting for a resource held by Thread A, then neither thread can make any forward progress. In this situation, Thread A and Thread B are said to be *deadlocked.*
+
+ For more information, see Deadlocks.
+
+## Which DB Handles are Free-Threaded
+
+The following describes to what extent and under what conditions individual handles are free-threaded.
+
+- `DbEnv`
+
+ Free-threaded so long as the `DB_THREAD` flag is provided to the environment `open()` method.
+
+- `Db`
+
+ Free-threaded so long as the `DB_THREAD` flag is provided to the database `open()` method, or if the database is opened using a free-threaded environment handle.
+
+- `Dbc`
+
+ Cursors are not free-threaded. However, they can be used by multiple threads of control so long as the application serializes access to the handle.
+
+- `DbTxn`
+
+ Access must be serialized by the application across threads of control.
diff --git a/docs_src/guides/gsg_txn/cxx/txncursor.md b/docs_src/guides/gsg_txn/cxx/txncursor.md
new file mode 100644
index 000000000..17f894218
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/txncursor.md
@@ -0,0 +1,69 @@
+---
+title: "Transactional Cursors"
+api-name: "Transactional Cursors"
+source: docs/gsg_txn/CXX/txncursor.html
+---
+## Transactional Cursors
+
+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:
+
+``` c
+#include "db_cxx.h"
+
+...
+
+int main(void)
+{
+ // Environment and database opens omitted
+ ...
+
+ DbTxn *txn = NULL;
+ Dbc *cursorp = NULL;
+
+ try {
+
+ Dbt key, data;
+ key.set_data(keystr);
+ key.set_size((strlen(keystr) + 1) * sizeof(char));
+ key.set_data(datastr);
+ key.set_size((strlen(datastr) + 1) * sizeof(char));
+
+ DbTxn *txn = NULL;
+ myEnv.txn_begin(NULL, &txn, 0);
+ try {
+ // Get our cursor. Note that we pass the transaction handle
+ // here.
+ db.cursor(txn, &cursorp, 0);
+
+ // Perform our operations. Note that we do not pass a
+ // transaction handle here.
+ char *replacementString = "new string";
+ while (cursor->get(&key, &data, DB_NEXT) == 0) {
+ data.set_data(void *)replacementString);
+ data.set_size((strlen(replacementString) + 1) *
+ sizeof(char));
+ cursor->put(&key, &data, DB_CURRENT);
+ }
+
+ // We're done. Commit the transaction.
+ cursor->close();
+ txn->commit(0);
+ } catch (DbException &e) {
+ std::cerr << "Error in transaction: "
+ << e.what() << std::endl;
+ cursor->close();
+ txn->abort();
+ }
+
+ } catch(DbException &e) {
+ std::cerr << "Error opening database and environment: "
+ << file_name << ", "
+ << envHome << std::endl;
+ std::cerr << e.what() << std::endl;
+ }
+
+ return (EXIT_SUCCESS);
+}
+```
diff --git a/docs_src/guides/gsg_txn/cxx/txnexample_c.md b/docs_src/guides/gsg_txn/cxx/txnexample_c.md
new file mode 100644
index 000000000..57c410dfd
--- /dev/null
+++ b/docs_src/guides/gsg_txn/cxx/txnexample_c.md
@@ -0,0 +1,474 @@
+---
+title: "Transaction Example"
+api-name: "Transaction Example"
+source: docs/gsg_txn/CXX/txnexample_c.html
+---
+## Transaction Example
+
+The following code provides a fully functional example of a multi-threaded transactional DB application. For improved portability across platforms, this examples uses pthreads to provide threading support.
+
+The example opens an environment and database and then creates 5 threads, each of which writes 500 records to the database. The keys used for these writes are pre-determined strings, while the data is a random value. This means that the actual data is arbitrary and therefore uninteresting; we picked it only because it requires minimum code to implement and therefore will stay out of the way of the main points of this example.
+
+Each thread writes 10 records under a single transaction before committing and writing another 10 (this is repeated 50 times). At the end of each transaction, but before committing, each thread calls a function that uses a cursor to read every record in the database. We do this in order to make some points about database reads in a transactional environment.
+
+Of course, each writer thread performs deadlock detection as described in this manual. In addition, normal recovery is performed when the environment is opened.
+
+We start with our normal `include` directives:
+
+``` c
+// File TxnGuide.cpp
+
+// We assume an ANSI-compatible compiler
+#include | File Type | +To Override | +
|---|---|
| database files | +You can cause database files to be created in a directory other than the environment home by using the This method modifies the directory used for database files created and managed by a single environment handle; it does not configure the entire environment. +You can also set a default data location that is used by the entire environment by using the |
+
| Log files | +You can cause log files to be created in a directory other than the environment home directory by using the This method modifies the directory used for database files created and managed by a single environment handle; it does not configure the entire environment. +You can also set a default log file location that is used by the entire environment by using the |
+
| Temporary files | +You can cause temporary files required by the environment to be created in a directory other than the environment home directory by using the You can also set a temporary file location by using the |
+
| Metadata files | +You can cause persistent metadata files required by the replicated applications to be created in a directory other than the environment home directory by using the You can also set a metadata directory location by using the |
+
| Region files | +If backed by the filesystem, region files are always placed in the environment home directory. | +
| Degree | +ANSI Term | +Definition | +
|---|---|---|
| 1 | +READ UNCOMMITTED | +Uncommitted reads means that one transaction will never overwrite another transaction's dirty data. Dirty data is data that a transaction has modified but not yet committed to the underlying data store. However, uncommitted reads allows a transaction to see data dirtied by another transaction. In addition, a transaction may read data dirtied by another transaction, but which subsequently is aborted by that other transaction. In this latter case, the reading transaction may be reading data that never really existed in the database. | +
| 2 | +READ COMMITTED | +Committed read isolation means that degree 1 is observed, except that dirty data is never read. +In addition, this isolation level guarantees that data will never change so long as it is addressed by the cursor, but the data may change before the reading cursor is closed. In the case of a transaction, data at the current cursor position will not change, but once the cursor moves, the previous referenced data can change. This means that readers release read locks before the cursor is closed, and therefore, before the transaction completes. Note that this level of isolation causes the cursor to operate in exactly the same way as it does in the absence of a transaction. |
+
| 3 | +SERIALIZABLE | +Committed read is observed, plus the data read by a transaction, T, will never be dirtied by another transaction before T completes. This means that both read and write locks are not released until the transaction completes. +In addition, no transactions will see phantoms. Phantoms are records returned as a result of a search, but which were not seen by the same transaction when the identical search criteria was previously used. +This is DB's default isolation guarantee. |
+
db_deadlock reference documentation.
+
+### Resolving Deadlocks
+
+When DB determines that a deadlock has occurred, it will select a thread of control to resolve the deadlock and then throws `DeadlockException` in that thread. If a deadlock is detected, the thread must:
+
+1. Cease all read and write operations.
+
+2. Close all open cursors.
+
+3. Abort the transaction.
+
+4. Optionally retry the operation. If your application retries deadlocked operations, the new attempt must be made using a new transaction.
+
+### Note
+
+If a thread has deadlocked, it may not make any additional database calls using the handle that has deadlocked.
+
+For example:
+
+``` c
+// retry_count is a counter used to identify how many times
+// we've retried this operation. To avoid the potential for
+// endless looping, we won't retry more than MAX_DEADLOCK_RETRIES
+// times.
+
+// txn is a transaction handle.
+// key and data are DatabaseEntry handles. Their usage is not shown here.
+while (retry_count < MAX_DEADLOCK_RETRIES) {
+ try {
+ txn = myEnv.beginTransaction(null, null);
+ myDatabase.put(txn, key, data);
+ txn.commit();
+ return 0;
+ } catch (DeadlockException de) {
+ try {
+ // Abort the transaction and increment the
+ // retry counter
+ txn.abort();
+ retry_count++;
+ if (retry_count >= MAX_DEADLOCK_RETRIES) {
+ System.err.println("Exceeded retry limit. Giving up.");
+ return -1;
+ }
+ } catch (DatabaseException ae) {
+ System.err.println("txn abort failed: " + ae.toString());
+ return -1;
+ }
+ } catch (DatabaseException e) {
+ try {
+ // Abort the transaction.
+ txn.abort();
+ } catch (DatabaseException ae) {
+ System.err.println("txn abort failed: " + ae.toString());
+ return -1;
+ }
+ }
+}
+```
+
+### Setting Transaction Priorities
+
+Normally when a thread of control must be selected to resolve a deadlock, DB decides which thread will perform the resolution; you have no way of knowing in advance which thread will be selected to resolve the deadlock.
+
+However, there may be situations where you know it is better for one thread to resolve a deadlock over another thread. As an example, if you have a background thread running data management activities, and another thread responding to user requests, you might want deadlock resolution to occur in the background thread because you can better afford the throughput costs there. Under these circumstances, you can identify which thread of control will be selected for resolved deadlocks by setting a transaction priorities.
+
+When two transactions are deadlocked, DB will abort the transaction with the lowest priority. By default, every transaction is given a priority of 100. However, you can set a different priority on a transaction-by-transaction basis by using the `Transaction.setPriority()` method.
+
+When two or more transactions are tied for the lowest priority, the tie is broken based on the policy provided to the `LockDetectMode` class. You provide this configuration object to the environment using the `EnvironmentConfig.setLockDetectMode()` method.
+
+A transaction's priority can be changed at any time after the transaction handle has been created and before the transaction has been resolved (committed or aborted). For example:
+
+``` c
+...
+
+try {
+
+ ...
+
+ Transaction txn = myEnv.beginTransaction(null, null);
+ txn.setPriority(200);
+
+ try {
+ myDatabase.put(txn, key, data);
+ txn.commit();
+ } catch (Exception e) {
+ if (txn != null) {
+ txn.abort();
+ txn = null;
+ }
+ }
+
+ ...
+
+}
+```
diff --git a/docs_src/guides/gsg_txn/java/logconfig.md b/docs_src/guides/gsg_txn/java/logconfig.md
new file mode 100644
index 000000000..904dce9a2
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/logconfig.md
@@ -0,0 +1,127 @@
+---
+title: "Configuring the Logging Subsystem"
+api-name: "Configuring the Logging Subsystem"
+source: docs/gsg_txn/JAVA/logconfig.html
+---
+## Configuring the Logging Subsystem
+
+ [Setting the Log File Size](logconfig.md#logfilesize)
+
+ [Configuring the Logging Region Size](logconfig.md#logregionsize)
+
+ [Configuring In-Memory Logging](logconfig.md#inmemorylogging)
+
+ [Setting the In-Memory Log Buffer Size](logconfig.md#logbuffer)
+
+You can configure the following aspects of the logging subsystem:
+
+- Size of the log files.
+
+- Size of the logging subsystem's region. See Configuring the Logging Region Size.
+
+- Maintain logs entirely in-memory. See Configuring In-Memory Logging for more information.
+
+- Size of the log buffer in memory. See Setting the In-Memory Log Buffer Size.
+
+- On-disk location of your log files. See Identifying Specific File Locations.
+
+### Setting the Log File Size
+
+Whenever a pre-defined amount of data is written to a log file (10 MB by default), DB stops using the current log file and starts writing to a new file. You can change the maximum amount of data contained in each log file by using the `EnvironmentConfig.setMaxLogFileSize()` method. Note that this method can be used at any time during an application's lifetime.
+
+Setting the log file size to something larger than its default value is largely a matter of convenience and a reflection of the application's preference in backup media and frequency. However, if you set the log file size too low relative to your application's traffic patterns, you can cause yourself trouble.
+
+From a performance perspective, setting the log file size to a low value can cause your active transactions to pause their writing activities more frequently than would occur with larger log file sizes. Whenever a transaction completes the log buffer is flushed to disk. Normally other transactions can continue to write to the log buffer while this flush is in progress. However, when one log file is being closed and another created, all transactions must cease writing to the log buffer until the switch over is completed.
+
+Beyond performance concerns, using smaller log files can cause you to use more physical files on disk. As a result, your application could run out of log sequence numbers, depending on how busy your application is.
+
+Every log file is identified with a 10 digit number. Moreover, the maximum number of log files that your application is allowed to create in its lifetime is 2,000,000,000.
+
+For example, if your application performs 6,000 transactions per second for 24 hours a day, and you are logging 500 bytes of data per transaction into 10 MB log files, then you will run out of log files in around 221 years:
+
+``` c
+ (10 * 2^20 * 2000000000) / (6000 * 500 * 365 * 60 *60 * 24) = 221
+```
+
+However, if you were writing 2000 bytes of data per transaction, and using 1 MB log files, then the same formula shows you running out of log files in 5 years time.
+
+All of these time frames are quite long, to be sure, but if you do run out of log files after, say, 5 years of continuous operations, then you must reset your log sequence numbers. To do so:
+
+1. Backup your databases as if to prepare for catastrophic failure. See Backup Procedures for more information.
+
+2. Reset the log file's sequence number using the **db_load** utility's `-r` option.
+
+3. Remove all of the log files from your environment. Note that this is the only situation in which all of the log files are removed from an environment; in all other cases, at least a single log file is retained.
+
+4. Restart your application.
+
+### Configuring the Logging Region Size
+
+The logging subsystem's default region size is 60 KB. The logging region is used to store filenames, and so you may need to increase its size if a large number of files (that is, if you have a very large number of databases) will be opened and registered with DB's log manager.
+
+You can set the size of your logging region by using the `EnvironmentConfig.setLogRegionSize()` method. Note that this method can only be called before the first environment handle for your application is opened.
+
+### Configuring In-Memory Logging
+
+It is possible to configure your logging subsystem such that logs are maintained entirely in memory. When you do this, you give up your transactional durability guarantee. Without log files, you have no way to run recovery so any system or software failures that you might experience can corrupt your databases.
+
+However, by giving up your durability guarantees, you can greatly improve your application's throughput by avoiding the disk I/O necessary to write logging information to disk. In this case, you still retain your transactional atomicity, consistency, and isolation guarantees.
+
+To configure your logging subsystem to maintain your logs entirely in-memory:
+
+- Make sure your log buffer is capable of holding all log information that can accumulate during the longest running transaction. See Setting the In-Memory Log Buffer Size for details.
+
+- Do not run normal recovery when you open your environment. In this configuration, there are no log files available against which you can run recovery. As a result, if you specify recovery when you open your environment, it is ignored.
+
+- Specify `true` to the `EnvironmentConfig.setLogInMemory()` method. Note that you must specify this before your application opens its first environment handle.
+
+For example:
+
+``` c
+package db.txn;
+
+import com.sleepycat.db.Database;
+import com.sleepycat.db.DatabaseConfig;
+import com.sleepycat.db.DatabaseEntry;
+import com.sleepycat.db.DatabaseException;
+import com.sleepycat.db.Environment;
+import com.sleepycat.db.EnvironmentConfig;
+
+import java.io.File;
+
+...
+
+Database myDatabase = null;
+Environment myEnv = null;
+try {
+ EnvironmentConfig myEnvConfig = new EnvironmentConfig();
+ myEnvConfig.setInitializeCache(true);
+ myEnvConfig.setInitializeLocking(true);
+ myEnvConfig.setInitializeLogging(true);
+ myEnvConfig.setTransactional(true);
+
+ // Specify in-memory logging
+ myEnvConfig.setLogInMemory(true);
+
+ // Specify the in-memory log buffer size.
+ myEnvConfig.setLogBufferSize(10 * 1024 * 1024);
+
+ myEnv = new Environment(new File("/my/env/home"),
+ myEnvConfig);
+
+ // From here, you open databases, create transactions and
+ // perform database operations exactly as you would if you
+ // were logging to disk. This part is omitted for brevity.
+```
+
+### Setting the In-Memory Log Buffer Size
+
+When your application is configured for on-disk logging (the default behavior for transactional applications), log information is stored in-memory until the storage space fills up, or a transaction commit forces the log information to be flushed to disk.
+
+It is possible to increase the amount of memory available to your file log buffer. Doing so improves throughput for long-running transactions, or for transactions that produce a large amount of data.
+
+When you have your logging subsystem configured to maintain your log entirely in memory (see Configuring In-Memory Logging), it is very important to configure your log buffer size because the log buffer must be capable of holding all log information that can accumulate during the longest running transaction. You must make sure that the in-memory log buffer size is large enough that no transaction will ever span the entire buffer. You must also avoid a state where the in-memory buffer is full and no space can be freed because a transaction that started the first log "file" is still active.
+
+When your logging subsystem is configured for on-disk logging, the default log buffer space is 32 KB. When in-memory logging is configured, the default log buffer space is 1 MB.
+
+You can increase your log buffer space using the `EnvironmentConfig.setLogBufferSize()` method. Note that this method can only be called before the first environment handle for your application is opened.
diff --git a/docs_src/guides/gsg_txn/java/logfileremoval.md b/docs_src/guides/gsg_txn/java/logfileremoval.md
new file mode 100644
index 000000000..b4a16b37b
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/logfileremoval.md
@@ -0,0 +1,42 @@
+---
+title: "Removing Log Files"
+api-name: "Removing Log Files"
+source: docs/gsg_txn/JAVA/logfileremoval.html
+---
+## Removing Log Files
+
+By default DB does not delete log files for you. For this reason, DB's log files will eventually grow to consume an unnecessarily large amount of disk space. To guard against this, you should periodically take administrative action to remove log files that are no longer in use by your application.
+
+You can remove a log file if all of the following are true:
+
+- the log file is not involved in an active transaction.
+
+- a checkpoint has been performed *after* the log file was created.
+
+- the log file is not the only log file in the environment.
+
+- the log file that you want to remove has already been included in an offline or hot backup. Failure to observe this last condition can cause your backups to be unusable.
+
+DB provides several mechanisms to remove log files that meet all but the last criteria (DB has no way to know which log files have already been included in a backup). The following mechanisms make it easy to remove unneeded log files, but can result in an unusable backup if the log files are not first saved to your archive location. All of the following mechanisms automatically delete unneeded log files for you:
+
+- Run the **db_archive** command line utility with the `-d` option.
+
+- From within your application, call the `Environment.removeOldLogFiles()` method.
+
+- Specify `true` to the `EnvironmentConfig.setLogAutoRemove()` method. Note that setting this property affects all environment handles opened against the environment; not just the handle used to set the property.
+
+ Note that unlike the other log removal mechanisms identified here, this method actually causes log files to be removed on an on-going basis as they become unnecessary. This is extremely desirable behavior if what you want is to use the absolute minimum amount of disk space possible for your application. This mechanism *will* leave you with the log files that are required to run normal recovery. However, it is highly likely that this mechanism will prevent you from running catastrophic recovery.
+
+ Do NOT use this mechanism if you want to be able to perform catastrophic recovery, or if you want to be able to maintain a hot backup.
+
+In order to safely remove log files and still be able to perform catastrophic recovery, use the **db_archive** command line utility as follows:
+
+1. Run either a normal or hot backup as described in Backup Procedures. Make sure that all of this data is safely stored to your backup media before continuing.
+
+2. If you have not already done so, perform a checkpoint. See Checkpoints for more information.
+
+3. If you are maintaining a hot backup, perform the hot backup procedure as described in Using Hot Failovers.
+
+4. Run the **db_archive** command line utility with the `-d` option against your production environment.
+
+5. Run the **db_archive** command line utility with the `-d` option against your failover environment, if you are maintaining one.
diff --git a/docs_src/guides/gsg_txn/java/maxtxns.md b/docs_src/guides/gsg_txn/java/maxtxns.md
new file mode 100644
index 000000000..bd58fb371
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/maxtxns.md
@@ -0,0 +1,71 @@
+---
+title: "Configuring the Transaction Subsystem"
+api-name: "Configuring the Transaction Subsystem"
+source: docs/gsg_txn/JAVA/maxtxns.html
+---
+## Configuring the Transaction Subsystem
+
+Most of the configuration activities that you need to perform for your transactional DB application will involve the locking and logging subsystems. See Concurrency and Managing DB Files for details.
+
+However, there are a couple of things that you can do to configure your transaction subsystem directly. These things are:
+
+-
+
+ Configure the maximum number of simultaneous transactions needed by your application. In general, you should not need to do this unless you use deeply nested transactions or you have many threads all of which have active transactions. In addition, you may need to configure a higher maximum number of transactions if you are using snapshot isolation. See Snapshot Isolation Transactional Requirements for details.
+
+ By default, your application can support 20 active transactions.
+
+ You can set the maximum number of simultaneous transactions supported by your application using `EnvironmentConfig.setTxnMaxActive()`.
+
+ If your application has exceeded this maximum value, then any attempt to begin a new transaction will fail.
+
+ This value can also be set using the `DB_CONFIG` file's `set_tx_max` parameter. Remember that the `DB_CONFIG` must reside in your environment home directory.
+
+-
+
+ Configure the timeout value for your transactions. This value represents the longest period of time a transaction can be active. Note, however, that transaction timeouts are checked only when DB examines its lock tables for blocked locks (see Locks, Blocks, and Deadlocks for more information). Therefore, a transaction's timeout can have expired, but the application will not be notified until DB has a reason to examine its lock tables.
+
+ Be aware that some transactions may be inappropriately timed out before the transaction has a chance to complete. You should therefore use this mechanism only if you know your application might have unacceptably long transactions and you want to make sure your application will not stall during their execution. (This might happen if, for example, your transaction blocks or requests too much data.)
+
+ Note that by default transaction timeouts are set to 0 seconds, which means that they never time out.
+
+ To set the maximum timeout value for your transactions, use the `EnvironmentConfig.setTxnTimeout()` method. This method configures the entire environment; not just the handle used to set the configuration. Further, this value may be set at any time during the application's lifetime. (Use `Environment.setConfig()` to set this value after the environment has been opened.)
+
+ This value can also be set using the `DB_CONFIG` file's `set_txn_timeout` parameter.
+
+For example:
+
+``` c
+package db.txn;
+
+import com.sleepycat.db.Environment;
+import com.sleepycat.db.EnvironmentConfig;
+import com.sleepycat.db.LockDetectMode;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+...
+
+Environment myEnv = null;
+try {
+ EnvironmentConfig myEnvConfig = new EnvironmentConfig();
+ myEnvConfig.setTransactional(true);
+ myEnvConfig.setInitializeCache(true);
+ myEnvConfig.setInitializeLocking(true);
+ myEnvConfig.setInitializeLogging(true);
+
+ // Configure a maximum transaction timeout of 1 second.
+ myEnvConfig.setTxnTimeout(1000000);
+ // Configure 40 maximum transactions.
+ myEnv.setTxnMaxActive(40);
+
+ myEnv = new Environment(new File("/my/env/home"),
+ myEnvConfig);
+
+ // From here, you open your databases (or store), proceed with your
+ // database or store operations, and respond to deadlocks as is
+ // normal (omitted for brevity).
+
+ ...
+```
diff --git a/docs_src/guides/gsg_txn/java/moreinfo.md b/docs_src/guides/gsg_txn/java/moreinfo.md
new file mode 100644
index 000000000..433070e89
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/moreinfo.md
@@ -0,0 +1,30 @@
+---
+title: "For More Information"
+api-name: "For More Information"
+source: docs/gsg_txn/JAVA/moreinfo.html
+---
+## For More Information
+
+ [Contact Us](moreinfo.md#contact_us)
+
+Beyond this manual, you may also find the following sources of information useful when building a transactional DB application:
+
+- Getting Started with Berkeley DB for Java
+
+- Berkeley DB Getting Started with Replicated Applications for Java
+
+- Berkeley DB Programmer's Reference Guide
+
+- Berkeley DB Javadoc
+
+- Berkeley DB Collections Tutorial
+
+To download the latest Berkeley DB documentation along with white papers and other collateral, visit http://www.oracle.com/technetwork/indexes/documentation/index.html.
+
+For the latest version of the Oracle Berkeley DB downloads, visit http://www.oracle.com/technetwork/database/berkeleydb/downloads/index.html.
+
+### Contact Us
+
+You can post your comments and questions at the Oracle Technology (OTN) forum for Oracle Berkeley DB at: http://forums.oracle.com/forums/forum.jspa?forumID=271, or for Oracle Berkeley DB High Availability at: http://forums.oracle.com/forums/forum.jspa?forumID=272.
+
+For sales or support information, email to: berkeleydb-info_us@oracle.com You can subscribe to a low-volume email announcement list for the Berkeley DB product family by sending email to: bdb-join@oss.oracle.com
diff --git a/docs_src/guides/gsg_txn/java/multithread-intro.md b/docs_src/guides/gsg_txn/java/multithread-intro.md
new file mode 100644
index 000000000..b228935b5
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/multithread-intro.md
@@ -0,0 +1,14 @@
+---
+title: "Multi-threaded and Multi-process Applications"
+api-name: "Multi-threaded and Multi-process Applications"
+source: docs/gsg_txn/JAVA/multithread-intro.html
+---
+## Multi-threaded and Multi-process Applications
+
+DB is designed to support multi-threaded and multi-process applications, but their usage means you must pay careful attention to issues of concurrency. Transactions help your application's concurrency by providing various levels of isolation for your threads of control. In addition, DB provides mechanisms that allow you to detect and respond to deadlocks.
+
+*Isolation* means that database modifications made by one transaction will not normally be seen by readers from another transaction until the first commits its changes. Different threads use different transaction handles, so this mechanism is normally used to provide isolation between database operations performed by different threads.
+
+Note that DB supports different isolation levels. For example, you can configure your application to see uncommitted reads, which means that one transaction can see data that has been modified but not yet committed by another transaction. Doing this might mean your transaction reads data "dirtied" by another transaction, but which subsequently might change before that other transaction commits its changes. On the other hand, lowering your isolation requirements means that your application can experience improved throughput due to reduced lock contention.
+
+For more information on concurrency, on managing isolation levels, and on deadlock detection, see Concurrency.
diff --git a/docs_src/guides/gsg_txn/java/nestedtxn.md b/docs_src/guides/gsg_txn/java/nestedtxn.md
new file mode 100644
index 000000000..875d27cae
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/nestedtxn.md
@@ -0,0 +1,33 @@
+---
+title: "Nested Transactions"
+api-name: "Nested Transactions"
+source: docs/gsg_txn/JAVA/nestedtxn.html
+---
+## Nested Transactions
+
+A *nested transaction* is used to provide a transactional guarantee for a subset of operations performed within the scope of a larger transaction. Doing this allows you to commit and abort the subset of operations independently of the larger transaction.
+
+The rules to the usage of a nested transaction are as follows:
+
+- While the nested (child) transaction is active, the parent transaction may not perform any operations other than to commit or abort, or to create more child transactions.
+
+- Committing a nested transaction has no effect on the state of the parent transaction. The parent transaction is still uncommitted. However, the parent transaction can now see any modifications made by the child transaction. Those modifications, of course, are still hidden to all other transactions until the parent also commits.
+
+- Likewise, aborting the nested transaction has no effect on the state of the parent transaction. The only result of the abort is that neither the parent nor any other transactions will see any of the database modifications performed under the protection of the nested transaction.
+
+- If the parent transaction commits or aborts while it has active children, the child transactions are resolved in the same way as the parent. That is, if the parent aborts, then the child transactions abort as well. If the parent commits, then whatever modifications have been performed by the child transactions are also committed.
+
+- The locks held by a nested transaction are not released when that transaction commits. Rather, they are now held by the parent transaction until such a time as that parent commits.
+
+- Any database modifications performed by the nested transaction are not visible outside of the larger encompassing transaction until such a time as that parent transaction is committed.
+
+- The depth of the nesting that you can achieve with nested transaction is limited only by memory.
+
+To create a nested transaction, simply pass the parent transaction's handle when you created the nested transaction's handle. For example:
+
+``` c
+ // parent transaction
+ Transaction parentTxn = myEnv.beginTransaction(null, null);
+ // child transaction
+ Transaction childTxn = myEnv.beginTransaction(parentTxn, null);
+```
diff --git a/docs_src/guides/gsg_txn/java/nodurabletxn.md b/docs_src/guides/gsg_txn/java/nodurabletxn.md
new file mode 100644
index 000000000..64cdec0bd
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/nodurabletxn.md
@@ -0,0 +1,30 @@
+---
+title: "Non-Durable Transactions"
+api-name: "Non-Durable Transactions"
+source: docs/gsg_txn/JAVA/nodurabletxn.html
+---
+## Non-Durable Transactions
+
+As previously noted, by default transaction commits are durable because they cause the modifications performed under the transaction to be synchronously recorded in your on-disk log files. However, it is possible to use non-durable transactions.
+
+You may want non-durable transactions for performance reasons. For example, you might be using transactions simply for the isolation guarantee. In this case, you might not want a durability guarantee and so you may want to prevent the disk I/O that normally accompanies a transaction commit.
+
+There are several ways to remove the durability guarantee for your transactions:
+
+- Specify `true` to the `EnvironmentConfig.setTxnNoSync()` method. This causes DB to not synchronously force any log data to disk upon transaction commit. That is, the modifications are held entirely in the in-memory cache and the logging information is not forced to the filesystem for long-term storage. Note, however, that the logging data will eventually make it to the filesystem (assuming no application or OS crashes) as a part of DB's management of its logging buffers and/or cache.
+
+ This form of a commit provides a weak durability guarantee because data loss can occur due to an application, JVM, or OS crash.
+
+ This behavior is specified on a per-environment handle basis. In order for your application to exhibit consistent behavior, you need to specify this method for all of the environment handles used in your application.
+
+ You can achieve this behavior on a transaction by transaction basis by using `Transaction.commitNoSync()` to commit your transaction, or by specifying `true` to the `TransactionConfig.setNoSync()` method when starting the transaction.
+
+- Specify `true` to the `EnvironmentConfig.setTxnWriteNoSync()` method. This causes logging data to be synchronously written to the OS's file system buffers upon transaction commit. The data will eventually be written to disk, but this occurs when the operating system chooses to schedule the activity; the transaction commit can complete successfully before this disk I/O is performed by the OS.
+
+ This form of commit protects you against application and JVM crashes, but not against OS crashes. This method offers less room for the possibility of data loss than does `EnvironmentConfig.setTxnNoSync()`.
+
+ This behavior is specified on a per-environment handle basis. In order for your application to exhibit consistent behavior, you need to specify this method for all of the environment handles used in your application.
+
+ You can achieve this behavior on a transaction by transaction basis by using `Transaction.commitWriteNoSync()` to commit your transaction, or by specifying `true` to `TransactionConfig.setWriteNoSync()` method when starting the transaction.
+
+- Maintain your logs entirely in-memory. In this case, your logs are never written to disk. The result is that you lose all durability guarantees. See Configuring In-Memory Logging for more information.
diff --git a/docs_src/guides/gsg_txn/java/perftune-intro.md b/docs_src/guides/gsg_txn/java/perftune-intro.md
new file mode 100644
index 000000000..0d50cc1a3
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/perftune-intro.md
@@ -0,0 +1,10 @@
+---
+title: "Performance Tuning"
+api-name: "Performance Tuning"
+source: docs/gsg_txn/JAVA/perftune-intro.html
+---
+## Performance Tuning
+
+From a performance perspective, the use of transactions is not free. Depending on how you configure them, transaction commits usually require your application to perform disk I/O that a non-transactional application does not perform. Also, for multi-threaded and multi-process applications, the use of transactions can result in increased lock contention due to extra locking requirements driven by transactional isolation guarantees.
+
+There is therefore a performance tuning component to transactional applications that is not applicable for non-transactional applications (although some tuning considerations do exist whether or not your application uses transactions). Where appropriate, these tuning considerations are introduced in the following chapters. However, for a more complete description of them, see the Transaction tuning and Transaction throughput sections of the *Berkeley DB Programmer's Reference Guide*.
diff --git a/docs_src/guides/gsg_txn/java/preface.md b/docs_src/guides/gsg_txn/java/preface.md
new file mode 100644
index 000000000..c9073a379
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/preface.md
@@ -0,0 +1,60 @@
+---
+title: "Preface"
+api-name: "Preface"
+source: docs/gsg_txn/JAVA/preface.html
+---
+## Preface
+
+**Table of Contents**
+
+ [Conventions Used in this Book](preface.md#conventions)
+
+ [For More Information](moreinfo.md)
+
+ [Contact Us](moreinfo.md#contact_us)
+
+This document describes how to use transactions with your Berkeley DB applications. It is intended to describe how to transaction protect your application's data. The APIs used to perform this task are described here, as are the environment infrastructure and administrative tasks required by a transactional application. This book also describes multi-threaded and multi-process DB applications and the requirements they have for deadlock detection.
+
+This book describes Berkeley DB 11*g* Release 2, which provides library version 11.2.5.3.
+
+This book is aimed at the software engineer responsible for writing a transactional DB application.
+
+This book assumes that you have already read and understood the concepts contained in the *Getting Started with Berkeley DB* guide.
+
+## Conventions Used in this Book
+
+The following typographical conventions are used within in this manual:
+
+Class names are represented in `monospaced font`, as are `method names`. For example: "The `Environment()` constructor returns an `Environment` class object."
+
+Variable or non-literal text is presented in *italics*. For example: "Go to your *DB_INSTALL* directory."
+
+Program examples are displayed in a `monospaced font` on a shaded background. For example:
+
+``` c
+import com.sleepycat.db.DatabaseConfig;
+
+...
+
+// Allow the database to be created.
+DatabaseConfig myDbConfig = new DatabaseConfig();
+myDbConfig.setAllowCreate(true);
+```
+
+In some situations, programming examples are updated from one chapter to the next. When this occurs, the new code is presented in **`monospaced bold`** font. For example:
+
+``` c
+import com.sleepycat.db.Database;
+import com.sleepycat.db.DatabaseConfig;
+
+...
+
+// Allow the database to be created.
+DatabaseConfig myDbConfig = new DatabaseConfig();
+myDbConfig.setAllowCreate(true);
+Database myDb = new Database("mydb.db", null, myDbConfig);
+```
+
+### Note
+
+Finally, notes of special interest are represented using a note block such as this.
diff --git a/docs_src/guides/gsg_txn/java/readmodifywrite.md b/docs_src/guides/gsg_txn/java/readmodifywrite.md
new file mode 100644
index 000000000..84c023ded
--- /dev/null
+++ b/docs_src/guides/gsg_txn/java/readmodifywrite.md
@@ -0,0 +1,76 @@
+---
+title: "Read/Modify/Write"
+api-name: "Read/Modify/Write"
+source: docs/gsg_txn/JAVA/readmodifywrite.html
+---
+## Read/Modify/Write
+
+If you are retrieving a record from the database or a class from the store for the purpose of modifying or deleting it, you should declare a read-modify-write cycle at the time that you read the record. Doing so causes DB to obtain write locks (instead of a read locks) at the time of the read. This helps to prevent deadlocks by preventing another transaction from acquiring a read lock on the same record while the read-modify-write cycle is in progress.
+
+Note that declaring a read-modify-write cycle may actually increase the amount of blocking that your application sees, because readers immediately obtain write locks and write locks cannot be shared. For this reason, you should use read-modify-write cycles only if you are seeing a large amount of deadlocking occurring in your application.
+
+In order to declare a read/modify/write cycle when you perform a read operation, specify `com.sleepycat.db.LockMode.RMW` to the database, cursor, `PrimaryIndex`, or `SecondaryIndex` get method.
+
+For example:
+
+``` c
+// Begin the deadlock retry loop as is normal.
+while (retry_count < MAX_DEADLOCK_RETRIES) {
+ try {
+ txn = myEnv.beginTransaction(null, null);
+
+ ...
+ // key and data are DatabaseEntry objects.
+ // Their usage is omitted for brevity.
+ ...
+
+ // Read the data. Declare the read/modify/write cycle here
+ myDatabase.get(txn, key, data, LockMode.RMW);
+
+ // Put the data. Note that you do not have to provide any
+ // additional flags here due to the read/modify/write
+ // cycle. Simply put the data and perform your deadlock
+ // detection as normal.
+ myDatabase.put(txn, key, data);
+ txn.commit();
+ return 0;
+ } catch (DeadlockException de) {
+ // Deadlock detection and exception handling omitted
+ // for brevity
+ ...
+```
+
+Or, with the DPL:
+
+``` c
+// Begin the deadlock retry loop as is normal
+ while (retry_count < MAX_DEADLOCK_RETRIES) {
+ try {
+ txn = myEnv.beginTransaction(null, null);
+
+ ...
+ // 'store' is an EntityStore and 'Inventory' is an entity class
+ // Their usage and implementation is omitted for brevity.
+ ...
+
+ // Read the data, using the PrimaryIndex for the entity object
+ PrimaryIndex