Table of Contents
While containers are the mechanism that you use to store and manage XML
documents, you use XmlManager
objects to create
and open XmlContainer
objects.
We therefore start with the XmlManager
.
XmlManager
is a high-level class used to
manage many of the objects that you use in a BDB XML application.
The following are some of the things you can do with
XmlManager
objects:
Manage containers. This management includes creating, opening, deleting, and renaming containers (see Managing Containers).
Create input streams used to load XML documents into containers (see Input Streams and Strings).
Create XmlDocument
and
XmlQueryContext
objects.
Prepare and run XQuery queries (see Using XQuery with BDB XML).
Create a transaction object (see the Berkeley DB XML Getting Started with Transaction Processing guide for details).
Because XmlManager
is the only way to
construct important BDB XML objects, it is central to your BDB XML
application.
Before you can instantiate an
XmlManager
object, you have to make
some decisions about your Berkeley DB Environment. BDB XML
requires you to use a database environment. You can use
an environment explicitly, or you can allow the
XmlManager
constructor to manage the
environment for you.
If you explicitly create an environment, then you can turn on important features in BDB XML such as logging, transactional support, and support for multithreaded and multiprocess applications. It also provides you with an on-disk location to store all of your application's containers.
If you allow the XmlManager
constructor to implicitly create and/or open an environment
for you, then the environment is only configured to allow
multithreaded sharing of the environment and the underlying
databases (DB_PRIVATE
is used). All other
features are not enabled for the environment.
The next several sections describe the things you need to know in order to create and open an environment explicitly. We start with this activity first because it is likely to be the first thing you will do for all but the most trivial of BDB XML applications.
In order to use an environment, you must first open it. When you do this, there are a series of configuration properties that you can optionally specify. These have the effect of enabling important subsystems (such as transactional support).
There are a great many environment configuration properties and these are described in the Berkeley DB documentation. However, there are a few that you are likely to want to use with your BDB XML application, so we describe them here:
EnvironmentConfig.setAllowCreate()
If true
and if
the environment does not exist at the time that
it is opened, then create it. It is an error to
attempt to open a database environment that has not
been created.
EnvironmentConfig.setInitializeLocking()
If true
, initializes
the locking subsystem. This
subsystem is used when an application employs multiple threads or processes
that are concurrently reading and writing Berkeley DB databases. In this
situation, the locking subsystem, along with a deadlock detector, helps to
prevent concurrent readers/writers from interfering with each other.
Remember that under the covers BDB XML containers are using Berkeley DB databases, so if you want your containers to be accessible by multiple threads and/or multiple processes, then you should enable this subsystem.
EnvironmentConfig.setInitializeLogging()
If true
, initializes
the logging subsystem. This subsystem is
used for database recovery from application or
system failures. For more information on normal and
catastrophic recovery, see the
Berkeley DB XML Getting Started with Transaction Processing guide.
EnvironmentConfig.setInitializeCache()
If true
, initializes
the shared memory pool subsystem. This
subsystem is required for multithreaded BDB XML
applications, and it provides an in-memory cache
that can be shared by all threads and processes
participating in this environment.
EnvironmentConfig.setTransactional()
If true
, initializes
the transaction subsystem. This
subsystem provides atomicity for multiple database
access operations. When transactions are in use,
recovery is possible if an error condition occurs
for any given operation within the transaction. If
this subsystem is turned on, then
the logging subsystem must also be turned on.
We discuss writing transactional applications in the Berkeley DB XML Getting Started with Transaction Processing guide.
EnvironmentConfig.setRunRecovery()
If true
, causes
normal recovery to be run against the underlying
database. Normal recovery ensures that the database files
are consistent relative to the operations recorded
in the log files. This is useful if, for example,
your application experienced an ungraceful shut down
and there is consequently an possibility that some
write operations were not flushed to disk.
Recovery can only be run if the logging subsystem is turned on. Also, recovery must only be run by a single thread of control; typically it is run by the application's master thread before any other database operations are performed.
Regardless of the
properties
you decide to set at creation time,
it is important to use the same ones on all subsequent
environment opens (the exception to this is
EnvironmentConfig.setAllowCreate()
which is only
required to create an environment). In
particular, avoid using
properties
to open environments that were not used at creation time. This
is because different subsystems require different data
structures on disk, and it is therefore illegal to attempt
to use subsystems that were not initialized when the
environment was first created.
To use an environment, you must first open it. At open time, you must identify the directory in which it resides and this directory must exist prior to the open attempt. At open time, you also specify the open if any, that you want to use for your environment.
When you are done with the environment, you must
make sure it is closed. You can either do this
explicitly, or you can have the XmlManager
object do it for you.
If you are explicitly closing your environment, you must
make sure any containers opened in the environment have
been closed before you close your environment.
Also, in this case, to ensure
that your environment is closed by your application, you
should perform this activity in the
finally
block of your
your application's top-level try block.
For information on XmlManager
instantiation, see
XmlManager Instantiation and Destruction
For example:
package dbxml.gettingStarted; import com.sleepycat.db.DatabaseException; import com.sleepycat.db.Environment; import com.sleepycat.db.EnvironmentConfig; import java.io.File; import java.io.FileNotFoundException; ... Environment myEnv = null; File envHome = new File("/export1/testEnv"); try { EnvironmentConfig envConf = new EnvironmentConfig(); envConf.setAllowCreate(true); // If the environment does not // exits, create it. envConf.setInitializeCache(true); // Turn on the shared memory // region. envConf.setInitializeLocking(true); // Turn on the locking subsystem. envConf.setInitializeLogging(true); // Turn on the logging subsystem. envConf.setTransactional(true); // Turn on the transactional // subsystem. myEnv = new Environment(envHome, envConf); // Do BDB XML work here. } catch (DatabaseException de) { // Exception handling goes here } catch (FileNotFoundException fnfe) { // Exception handling goes here } finally { try { if (myEnv != null) { myEnv.close(); } } catch (DatabaseException de) { // Exception handling goes here } }
You create an XmlManager
object by
calling its constructor. You destroy a XmlManager
object by calling its
close()
method.
Note that XmlManager
is closed
and all of its resources released when the last open handle
to the object is
closed.
To construct an XmlManager
object, you
may or may not provide the constructor with an
open
Environment
object. If you do instantiate XmlManager
with an opened environment handle, then XmlManager
will close and destroy that
Environment
object for you if you
set XmlManagerConfig::setAdoptEnvironment()
to true
.
If you provide an
Environment
object to the constructor, then you can use that object to use
whatever subsystems that you application may require (see
Environment Configuration Properties
for some common
subsystems).
If you do not provide an environment object,
then XmlManager
will implicitly create an environment for you. In this case, the
environment will not be
configured to use any subsystems and it is only
capable of being shared by multiple threads from within
the same process. Also, in this case you can optionally identify the
on-disk location where you want your containers to reside using
one of the following mechanisms:
Specify the path to the on-disk location in the container's name.
Specify the environment's data location using the
DB_HOME
environment variable.
In either case, you can pass the XmlManager
constructor a
XmlManagerConfig
object
that controls that object's behavior
with regard to the underlying containers (the
property
is NOT passed directly to the underlying environment or
databases).
Configuration methods are:
XmlManagerConfig.setAllowAutoOpen()
If set to true, XQuery queries that reference created but unopened containers will automatically cause the container to be opened for the duration of the query.
XmlManagerConfig.setAdoptEnvironment()
If set to true,
XmlManager
will close and
destroy the
Environment
object that it was instantiated with when the
XmlManager
is closed.
XmlManagerConfig.setAllowExternalAccess()
If set to true, XQuery queries executed from inside BDB XML can access external sources (URLs, files, and so forth).
For example, to instantiate an XmlManager
with a default environment:
package dbxml.gettingStarted; import com.sleepycat.dbxml.XmlException; import com.sleepycat.dbxml.XmlManager; ... XmlManager myManager = null; try { myManager = new XmlManager(); } catch (XmlException e) { // Exception handling goes here } finally { try { if (myManager != null) { myManager.close(); } } catch (XmlException ce) { // Exception handling goes here } }
And to instantiate an XmlManager
using an explicit
environment object:
package dbxml.gettingStarted; import com.sleepycat.db.DatabaseException; import com.sleepycat.db.Environment; import com.sleepycat.db.EnvironmentConfig; import com.sleepycat.dbxml.XmlException; import com.sleepycat.dbxml.XmlManager; import com.sleepycat.dbxml.XmlManagerConfig; import java.io.File; import java.io.FileNotFoundException; ... Environment myEnv = null; File envHome = new File("/export1/testEnv"); XmlManager myManager = null; try { EnvironmentConfig envConf = new EnvironmentConfig(); envConf.setAllowCreate(true); // If the environment does not // exits, create it. envConf.setInitializeCache(true); // Turn on the shared memory // region. envConf.setInitializeLocking(true); // Turn on the locking subsystem. envConf.setInitializeLogging(true); // Turn on the logging subsystem. envConf.setTransactional(true); // Turn on the transactional // subsystem. myEnv = new Environment(envHome, envConf); XmlManagerConfig managerConfig = new XmlManagerConfig(); managerConfig.setAdoptEnvironment(true); myManager = new XmlManager(myEnv, managerConfig); } catch (DatabaseException de) { // Exception handling goes here } catch (FileNotFoundException fnfe) { // Exception handling goes here } catch (XmlException e) { // Exception handling goes here } finally { try { if (myManager != null) { myManager.close(); } } catch (XmlException ce) { // Exception handling goes here } catch (DatabaseException de) { // Exception handling goes here } }