Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Having a tough time with Tx #25

Open
Mu4h4h4 opened this issue Apr 4, 2018 · 4 comments
Open

Having a tough time with Tx #25

Mu4h4h4 opened this issue Apr 4, 2018 · 4 comments
Labels

Comments

@Mu4h4h4
Copy link
Contributor

Mu4h4h4 commented Apr 4, 2018

Hello there!

I feel that I'm over complicating over, possibly overkilling it... but I need the following operations to be within a transaction:

  1. Update parent resource
  2. Delete orphan child resource
  3. Update child resource
  4. Insert new child resource
  5. Fetch just updated parent resource
  6. Fetch all child resources

My code looks like this so far...

        try (Database database = Database.fromBlocking(dataSource)) {
            return database.update(updateParentResourceQuery)
                    .parameter()
                    .transacted()
                    .counts()
                    .flatMap(tx -> {
                        return tx.update(deleteChildResource)
                                .parameter()
                                .counts()
                                .flatMap(tx2 -> {
                                    TransactedUpdateBuilder createChildResource = tx2.update(createChildResourceQuery);
                                    childResourcesToBeCreated.forEach(entityLanguage -> createChildResource
                                            .parameter());
                                    return createChildResource
                                            .counts()
                                            .flatMap(tx3 -> {
                                                TransactedUpdateBuilder updateChildResource = tx3.update(updateChildResourceQuery);
                                                childResourcesToBeUpdated.forEach(
                                                        entityLanguage -> updateChildResource
                                                                .parameter());
                                                return updateChildResource
                                                        .counts()
                                                        .flatMap(tx4 -> {
                                                            return tx4.select(selectParentResource)
                                                                    .parameter()
                                                                    .transactedValuesOnly()
                                                                    .get(new Mapper())
                                                                    .flatMap(tx5 -> {
                                                                        return tx5
                                                                                .select(selectAllChildResources)
                                                                                .parameter()
                                                                                .valuesOnly()
                                                                                .get(new Mapper())
                                                                                .flatMap(childResources -> {
                                                                                    ParentResource parentResource = tx5.value();
                                                                                    parentResource.setChildResources(childResources);
                                                                                    return Flowable.just(parentResource);
                                                                                });
                                                                    });
                                                        });
                                            });
                                });
                    });
        }

It doesn't work. When I do the parent update and fetch it back it works, but when I start chaining the operations everything goes haywire.

Any input will be much much appreciated!

Thank you very much for your time!

@davidmoten
Copy link
Owner

Yep that's ugly isn't it. We need some other patterns. I sometimes just block to get simpler code, that is an option. Once you have the first tx you can use that across a sequence of blocking calls if it's easier.

In terms of it working or not, I'd like to have a repeatable unit test, preferrably using Database.test() like in the README.md. If you can knock one up, great!

@Mu4h4h4
Copy link
Contributor Author

Mu4h4h4 commented Apr 4, 2018

When is the transaction commit/rollback? (since I could span the initial tx across multiple methods for each operation)
I will try to put up the test cases in a bit, for now I'm in a bit of a time crunch I'm giving the raw jdbc a go.

@davidmoten
Copy link
Owner

So throughout there is only one actual transaction of course and that is presented to you in that first tx. When that outer Flowable terminates then the transaction will be committed or rolled back as appropriate.

@davidmoten
Copy link
Owner

In terms of patterns I just remembered that in rxjava-jdbc we offered a dependsOn method. See https://github.com/davidmoten/rxjava-jdbc#dependencies. Once you've got a tx you start using it with dependsOn and no blocking required. Don't think rxjava2-jdbc has it but we can add it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants