Multiple Data Stores

Hi,

I don’t know how I should exactly manage the process of dealing with related entities belonging to different Data Stores. I went through the explanations where (Data Stores - CUBA Platform. Developer’s Manual) and I was able to associate entities to an additional datastore. However, although being the additional DataStore a relational mysql database, such as the Main Datastore, CUBA Studio won’t crete automatically the DDL code to handle DB scripts.

I read in the another link that to accomplish that the user is expected to implement a custom Data Source, but don’t understand why, if the additional datastore is to implement the same orm logic.

The main reasong why I would like to work with an additional datastore, is that I prefer to store files and images in a separate database, since size matters when considering maintainance and backup tasks.

So i would like to use a separate DAtaStore for storing file/image serializations. Can anybody point me in the right direction?

Perhaps Entity events and manually entering data in another database? Can I ensure everything is done in a transaction safe manner?

thanks and regards,

Carlos.

Hi @carloscz25,

There are some drawbacks when using an additional datasource, and this is one of them. The short answer is no, because there is no global transactions in CUBA by default (take a look at this answer in another topic).

To use global transactions, there are some alternatives (and each have its own drawbacks as well):

  • switch from tomcat to a JEE App Server (widlfly, glassfish, tomee, jboss eap, etc…)
  • configure JTA in tomcat using additional libraries (atomikos, narayana, etc…)

If you really want to use different databases, maybe you can configure your database to expose another schema to your database user, or use db links, foreign table, etc. when working with an external database, for example.

Regards,
Peterson.

Hi Peterson,

thanks for your reply.

I don’t have experience dealing with JTA or JEE Servers. Due to maintainance concerns and hardware size I have always tried to keep things simple regarding this very specific aspect. This is a complex subject and reaching a satisfactory setup at the end of the day might involve significant investigation.

So for now if possible I would prefer to avoid scenarios involving other servers than Tomcat, and directly dealing with JTA aspects. However according to your article, Spring should come to the rescue right?

Regarding the article you pointed, I understand I have 2 options that allow me to ensure that at least 2 transactions are done in a safely manner. A valid arrangement would be having 1 transaction for the main datastore and 1 transaction for my external db, where I serialize files/images. So what I would do is to start, execute and commit the second transaction within the execution bounds of the first one, and PlatformTransactionManager would enable to rollback the first transaction, upon Exception arisal in the second one.

To accomplish that, I would have 2 ways:

  1. Start, execute and commit a second transaction inside the doInTransaction() method. Upon Exception arisal, rollback second transaction and throw Exception to trigger rollback of the first (main) transaction.
@Inject private PlatformTransactionManager txManager; 

TransactionTemplate template  = new TransactionTemplate(this.txManager); 
template.execute( new TransactionCallback<Object>(){ 
     public void doInTransaction(TransactionStatus status){ 
       // work done here will be wrapped by a transaction and committed. 
       // the transaction will be rolled back if 
       // status.setRollbackOnly(true) is called or an exception is thrown 
    } 
 });

or 2) Include transaction methods in my ServiceBeans to ensure the execution of the second transaction and trigger the main rollback upon Exception

@Transactional
public void work() { 
  // the transaction will be rolled back if the 
  // method throws an Exception, otherwise committed
}

From my understanding that should suffice. Is my understanding correct?

Thanks for taking the time to help.

Regards,

Carlos.

Hi @carloscz25,

It is not as easy as it seems. My advice is that you use it only if really necessary. Spring does not implement JTA, it just provides abstractions to work with it, using the underlying JTA implementation from the application server.

If you still want to use it, there is a spring blog post about this topic (a bit outdated but the idea remains the same):

Regards,
Peterson.

Hi,

This sounds like a perfect task for a file storage. CUBA file storage was invented exactly for such tasks: storing unstructured big files.
https://doc.cuba-platform.com/manual-7.2/file_storage.html

Regarding following discussion about global transactions. Are you sure that you need them? They say that one shouldn’t use global transactions until desperately needs them (e.g. it is a customer requirement for the system).

Hi Alex,

thanks for your answer.

The logic in my program is as follows:

I fill out let’s say a Contract form. One of the fields is a reference to an Entity holding a bytearray as a database field.

I would like to store all the Contract fields in one db (main datastore) and the bytearrays in an additional datastore and entity, previously set the entity reference in the Contract entity. In the program I am trying to migrate I have the analogue main datastore at 1,5GB size, whereas the additional datastore is 30GB big!

So this poses a problem in maintainance and backups. Since at the end of the day I will have all the info stored in a db, I need them to remain separate.

However I believe that working with nested transactions should lead to satisfactory results aswell, then the dynamic would be, creating the first transaction, filling out the form, and on before commit the main transaction, manually create the second and commit it, and in case of an exception, rollback the first one. That would ensure no data is corrupt.

I could accomplish that by expressly marking the main transaction as rollback right?

On the other hand I don’t know how to create the database for the second datastore. CubaStudio says that DDL’s are not generated for entities in additional DataStores. Somewhere I read I should implement a DataSource, but don’t know exactly what that means.

Any help is greatly appreciated.
Regards,

Carlos.

This feature will be released with Studio 14 soon:
https://youtrack.cuba-platform.com/issue/STUDIO-4835

For now you can just create database manually, create tables manually and then import them as entities to the CUBA project with the “Generate model” feature.

Thanks for clarifying Alex.

Will give it a try with my legacy app.

regards,
Carlos.