Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Joining of threads | Really How do I roll back two related updates if one fails?

 
Raghu Sha
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I need to perform an Save operation after successful completion of DB update.
Two threads update different schema concurrently.
If any one fails, rollback entire operation.

If exception doesn't occurs then need to perform save operation.
How to join two threads?



 
Maxim Karvonen
Ranch Hand
Posts: 121
12
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Raghu.

Your question contains half of the answer. You need to use Thread.join method. In this case you will need to have some flag to set when a thread fails. Or you may use java.util.concurrent.ExecutorService and call a Future.get method. Using this approach you do not need to provide custom fields to receive an exception or result, all this is done by the library. Check ExecutorService, See and Future in java.util.concurrent package.
 
Raghu Sha
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks..

I had used 2 Future objects for calling above two methods.


The status always return true even transaction failure scenario also.
How to roll back the entire transactions (including db1 update ) any failure occurs
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Raghu Sha wrote:

The Future doesn't know anything about the database or the task it runs, whatever. It just knows is the task which it is tracking is completed, errored, or still working. So relying on Future#get() to tell you if the update was successful is not the route to go. Instead, you need the updateDB1() method to return a value based on success or failure, and return that result from the call() method. That way, your Future#get() will return a value indicating success or failure of the update.

 
Raghu Sha
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks..

What will be the return type of updateDB1()?
It should return Future object?
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Raghu Sha wrote:Thanks..

What will be the return type of updateDB1()?
It should return Future object?

No, it should return something that you can use to tell if the update was successful. A simple boolean would be fine, but maybe something else makes more sense (like the number of updated rows, or something). It depends on how you can detect success versus failure.

Remember to change all the generic types accordingly, for example, if you choose boolean you would do:

Then the .get() method will return a Boolean (which you can auto unbox into a boolean):
 
Raghu Sha
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Steve..

Created two Future objects for each DB operations?
Is it correct?

How i can roll back of first if latter one fails?
How i have to make communication between two future objects?

As per the requirement, if any one db update fails, roll back others also. (two db operations are simultaneously runs - used @Async)


Thanks..
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Raghu Sha wrote:Created two Future objects for each DB operations?
Is it correct?
One future per task. If 'each DB operation' is done in two tasks then yes, two futures. But I have no clue how you got the number two from my description... You never make the Future. You give the executor a task to run and it gives you a future to track it.

Raghu Sha wrote:How i can roll back of first if latter one fails?

You use the same transaction between both operations and don't commit until both are done? You look up the database manual to see if there is a way to undo an operation that is already committed? I don't know, it probably depends on the database and has nothing to do with joining threads.

How i have to make communication between two future objects?

Read this or better yet this.

As per the requirement, if any one db update fails, roll back others also. (two db operations are simultaneously runs - used @Async)

I have no idea what @Async does. It looks like an annotation, but not a standard one.

I am guessing your problem is not about beginner Java. It is either some database specific or framework specific question that you haven't told us about. And we aren't familiar enough to guess what you are using so as to give a good answer. I am going to move this to a different forum (a database centric one) where maybe someone has a better clue.

I will also add to the subject since, this isn't really related to joining threads, I don't think.
 
Raghu Sha
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Steve..

I am scheduling 3 tasks which needs to be run parallely. (insert/update/delete - 3 different schemas)
For simultaneous opeation only used @Async annotation.

ExecutorService exeService = Executors.newFixedThreadPool(3);
Need to give 3 or more than that to specify in ThreadPool to run 3 tasks simultaneously?

Used 3, but as per the link which you shared, but 3rd task is not executing.

 
Ulf Dittmer
Rancher
Posts: 42969
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If the DB should only be updated if all 3 tasks succeed, then it seems better to collect the results of all 3 tasks, and only then write to the DB, instead of writing to the DB from each task.

Why do those tasks need to run in parallel? Obviously there are some interdependencies between them. If just one of them fails, you'd be throwing away the work done by the other two (which may or may not be a big deal).
 
Raghu Sha
Ranch Hand
Posts: 122
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Used @Transactional annotation.

Issue is commiting transaction.
After sucessful opeartion, it should commit.
We need to specify explicitly to do commit like currentTransactionStatus().flush()?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic