This chapter discusses issues that will help improve the performance, reliability, and size of DataStore applications. Unless otherwise specified, DataStoreConnection refers to either a DataStoreConnection or DataStore object used to open a connection to a DataStore file.
Here are a few items that concern usage for all types of DataStore applications.
Be sure to call DataStoreConnection.close when the DataStoreConnection is no longer needed, or call DataStore.shutdown to close the DataStore file regardless of how many connections there may be. In particular:
Closing a DataStore ensures that all modifications are saved to disk. There is a daemon thread for all open DataStoreConnection instances that is constantly saving modified cache data (by default modified data is saved every 100 milliseconds). If you directly exit the Java VM, the daemon thread may not have the opportunity to save the last set of changes. There is a small chance that a non-transactional DataStore may get corrupted.
A transactional DataStore is guaranteed to not lose data, but the transaction manager will roll back any uncommitted changes.
If a DataStore file is not closed properly, it will take several seconds to reset/recover the DataStore file. Proper closure means that the DataStore will reopen quickly every time.
Another benefit to closing DataStoreConnection objects is that when they are all closed, the memory allocated to the DataStore cache is released.
Close all StorageDataSets that have their store property set to a DataStoreConnection when you are done with them. This frees up DataStore resources associated with the StorageDataSet and allows the StorageDataSet to be garbage collected.
Use the saveMode property of the DataStore component to control how often cache blocks are written to disk. This property applies only to non-transactional DataStores. The following are valid values for the method:
Unlike other properties of DataStore, saveMode may be changed when the connection is open. For example, if you are using a DataStoreConnection, you can access the value through the dataStore property:
DataStoreConnection store = new DataStoreConnection(); // ... store.getDataStore().setSaveMode(2);
Note that this will change the behavior for all DataStoreConnection objects that access that particular DataStore file.
You can tune the use of memory in a number of ways. Beware that asking for too much memory can be as bad as having too little.
The dbSwing component library provides two components (on the More dbswing page of the component palette) that make it easier to produce robust DataStore applications.
For example, if you drop a DBDisposeMonitor into a JFrame you're designing that contains dbSwing components attached to a DataStore, when you close the JFrame DBDisposeMonitor will automatically close the DataStore for you. This component is particularly handy when building simple applications to experiment with DataStore.
When using a DataStore with a StorageDataSet, it is strongly recommended that they all be grouped inside data modules. Any references to these StorageDataSets should be made through DataModule accessor methods such as businessModule.getCustomer(). The reason for this is that much of the functionality surfaced through StorageDataSets is driven by property and event settings. Although most of the important "structural" StorageDataSet properties are persisted in the DataStore itself, the classes that implement the event listener interfaces are not. By instantiating the StorageDataSet with all event listener settings, constraints, calculated fields, and filters implemented with events, they will be properly maintained at run time and design time.
The increased reliability and flexibility gained from using transactional DataStores comes at the price of some performance. You can reduce this cost in several ways.
For transactions that are reading but not writing, significant performance improvements can be realized by using a read-only transaction. The DataStoreConnection's readOnlyTx property controls whether a transaction is read-only. This property must be set to true before the connection is open. For JDBC connections, it is controlled by the readOnly property of the java.sql.Connection object (returned by the java.sql.DriverManager.getConnection and com.borland.dx.dataset.sql.Database.getJdbcConnection methods).
Read-only transactions work by simulating a snapshot of the DataStore. Only data from transactions committed at the point the transaction started are seen in this snapshot (otherwise, the connection would have to see if there are pending changes and roll them back whenever it accesses the data). A snapshot is taken when the DataStoreConnection is opened, and is refreshed every time its commit method is called.
Another benefit of read-only transactions is that they are not blocked by writers (or other readers). Both reading and writing normally require a stream lock. But because it uses a snapshot, a read-only transaction does not need a lock, and therefore would not be blocked by a writer that has a lock on a stream that it is modifying.
You can further optimize the application by specifying a readOnlyTxDelay. By default, this property is zero, which means that whenever a read-only transaction starts or is refreshed, a new snapshot is taken. The readOnlyTxDelay property specifies the maximum age (in milliseconds) for an existing snapshot that the connection can share. When the property is non-zero, existing snapshots are searched from most recent to oldest. If there is one that is under readOnlyTxDelay in age, it is used and no new snapshot is taken.
If you enable soft commit mode through the TxManager's softCommit property, the transaction manager will force disk writes for the purposes of crash recovery, but not guarantee transaction commits. This will improve performance, but make you slightly more susceptible to power loss, operating system crashes, and hardware failures.
Very recently committed transactions--depending on the operating system, but in general those committed within approximately the last second--are not guaranteed to be written. This is not the case when soft commit mode is disabled (the default), when committed changes are written immediately.
The location of the transaction log files is controlled by the TxManager's ALogDir and BLogDir properties.
You can also improve performance by disabling the logging of status messages. To do this, set the recordStatus property of the TxManager to false.
When deploying a DataStore application, you can exclude certain classes and graphics files that are not used. In particular:
pubsweb@borland.com
Copyright © 1999, Inprise Corporation. All rights reserved.