Search code examples
javajpaspring-bootrabbitmqtransactional

At what point can I trust that data has been saved to mysql?


After I create a new object 'Order', I would like to get its generated ID and put it on an AMQP queue, so that a worker can do other stuff with it. The worker takes the generated ID (message) and looks up the order but complains that no record exists, even though I just created one. I am trying to figure out either how long to wait for after I call my .persist() before I put the message (generated ID) on the queue (which I dont think is a good idea); have the worker loop over and over until mysql DOES return a record (which I dont like either); or find a point where I can put the message on the queue after I know the data is safe in mysql (this sounds best). Im thinking that it needs to be done outside of any @Transactional method.

The worker that is going to read the data back out of mysql is part of a different system on a different server. So when can I tell the worker that the data is in mysql so that it can get started with its task?

Is it true that after the @Transactional method finishes the data is done being written to mysql, I am having trouble understanding this. Thanks a million in advanced.


Solution

  • Is it true that after the @Transactional method finishes the data is done being written to mysql, I am having trouble understanding this. Thanks a million in advanced.

    So first, as Kayamann and Ralf wrote in comments, it is guaranteed that data is stored and available for other processes when the transaction commits (ends)

    @Transactional methods are easy to understand. When you have @Transactional method, it means that the container (application that is going to actually invoke that method) will begin the transaction before the method is invoked, and auto commit or rollback the transaction in case of success or error.

    So if we have

    @Transactional
    public void modify(){
       doSomething();
    }
    

    And when you call somewhere in the code (or invokation via contaier eg due to some bindings) the actuall frol will be as follows

    tx=entityManager.beginTransaction();
    object.modify();
    tx.commit();
    

    There is quite simple. Such approach will mean that transactions are Container Controlled

    As four your situation, well to let your external system know that transaction has been complete, you have to either use message queue (that you are using already) with the message that transaction is complete for some id and it can start processing stuff, or use different technology, REST for example.

    Remote systems can signal eachoter for various of events via queues and REST services, so there is no difference.