When the OM generates business object classes, it "stamps" them with the DataSourceKeyName specified in the Object Mapper. (It's the value in the "Key" column in the "Data Source Keys" grid.) Since your DBa and DBb databases have the same structure, you could use either of them for your design-time work. So, in the Object Mapper, you would add a second row to the Data Source Keys grid. You would point the first row to database DB1, and the second to DBa (or DBb, or any other database with the same structure).
When you instantiate a PersistenceManager (to retrieve and save objects), you can specify a DataSourceExtension (string). (If you don't specify one, it gets an extension consisting of an empty string.) Then when you ask that PM to retrieve some objects, it finds or creates a DataSourceKey (in memory) object based upon (1) the DataSourceKeyName embedded in the class for the objects of the type to be retrieved, and (2) the DataSourceExtension associated with the PersistenceManager. A DataSourceKeyResolver uses a method, GetKey(KeyName, KeyExtension) to find or create this DataSourceKey object. The object includes the connection string necessary to access a specify physical instance of the database.
For the purpose of discussion, let's say that, in the Data Source Keys grid in the Object Mapper, you leave the name of the key in the DB1 record as "default", but rename the one in the second row from "Key" to "secondary". Then in your code you instantiate a PersistenceManager using a overload of the PersistenceManager's constructor that let's you specify the extension, and that you specify an extension of "B". Then, when attempting to retrieve objects from your first database, your app would look for a key with a name of "default" and an extension of "". When attempting to retrieve objects from your second database, your app would look for a key with a name of "secondary" and an extension of "B". In either case, the first request for data from the the first database would result in the creation of one in-memory DataSourceKey object; and the first request for data from the secondary database would result in the creation of a second (and different) in-memory DataSourceKey object. Subsequent requests for data from either database would NOT result in the creation of any more DataSourceKeys; rather, the existing ones would be found and used.
You actually do not necessary need a custom DataSourceKeyResolver to make this work. If your ibconfig file has proper entries, the default resolver will find the right copy of the second database. The section of your ibconfig file containing RdbKeys, for example, might look like the following:
<rdbKey name="default" databaseProduct="Unknown">
<connection>Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Xyz;Data Source=.</connection>
<probeAssemblyName>Model</probeAssemblyName>
</rdbKey>
<rdbKey name="secondary_A" databaseProduct="Unknown">
<connection>Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Pdq;Data Source=.</connection>
<probeAssemblyName>Model</probeAssemblyName>
</rdbKey>
<rdbKey name="secondary_B" databaseProduct="Unknown">
<connection>Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Abc;Data Source=.</connection>
<probeAssemblyName>Model</probeAssemblyName>
</rdbKey>
The default DataSourceKeyResolver would find the rdbKey entry corresponding to the needed DataSourceKey by concatenating the DataSourceKeyName (obtained from the business object type) and the DataSourceExtension (obtained from the PersistenceManager) and comparing the result to the name specified in the rdbKey. Thus, if your app had instantiated the PM as follows:
...
datasourceExtensionName = "B";
PersistenceManager pm = new PersistenceManager (true, datasourceExtensionName);
...
then, while attempting the first retrieval of objects of a type sourced in the secondary database, it would create a DataSourceKey using information mined out of the third rdbKey entry above. It would therefore access the database named "Abc". Any subsequent request to access data in the same database would use the in-memory DataSourceKey object created for this first access; that is, DevForce would not go back to the ibconfig file.
The best source of further information about this is probably the section "DevForce and Data Sources – Digging Deeper", in Chapter 4 of the IdeaBlade DevForce Developers Guide.