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

Outdated documentation for JDBC Transaction management #558

Open
chrisparton1991 opened this issue Sep 23, 2021 · 22 comments
Open

Outdated documentation for JDBC Transaction management #558

chrisparton1991 opened this issue Sep 23, 2021 · 22 comments
Assignees

Comments

@chrisparton1991
Copy link

chrisparton1991 commented Sep 23, 2021

Expected Behavior

  1. Create a new project using https://launch.micronaut.io. Default settings, but with jdbc-hikari added:
    image

  2. Follow https://micronaut-projects.github.io/micronaut-sql/latest/guide/#jdbc to get transactions working.

Actual Behaviour

The docs are outdated around the "Using Spring Transaction Management" section.

image

Issue 1
Gradle is unable to resolve implementation("io.micronaut:micronaut-spring"). I changed this to implementation("io.micronaut.spring:micronaut-spring-annotation"), but not sure if this is correct as I don't have access to any variant of @Transactional.

Issue 2
The runtime scope has been removed from Gradle, so runtime("org.springframework:spring-jdbc") becomes runtimeOnly("org.springframework:spring-jdbc").

Changing runtimeOnly("org.springframework:spring-jdbc") to implementation("org.springframework:spring-jdbc") places org.springframework.transaction.annotation.Transactional onto my compile-time classpath, but I can't get the transaction interceptor to trigger.

Issue 3
The @Transactional link in the docs redirects to https://docs.micronaut.io/latest/api/io/micronaut/spring/tx/annotation/Transactional.html, which doesn't exist.

Issue 4
Not sure if limited to this page, but clicking the Improve this doc buttons yield a JS error, as the button link contains an unescaped newline:
image

Thanks!

Steps To Reproduce

  1. Launch the server
  2. Hit GET http://localhost:8080/test
  3. Receive "Roll back" error (expected)
  4. Hit GET http://localhost:8080/test
  5. Receive "table already exists" error, instead of the expected "roll back" error

If transactions were working, the table creation would be rolled back each time.

I've also debugged into io.micronaut.spring.tx.annotation.TransactionInterceptor#intercept and can confirm that it's not being fired. The datasource is, however, wrapped in a TransactionAwareDataSourceProxy.

Environment Information

  • Operating System: Windows 10 Pro
  • JDK Version: AdoptOpenJDK 11.0.7

Example Application

https://github.com/chrisparton1991/micronaut-transaction-test

Version

3.0.1 (also reproducible in 2.5.11)

@chrisparton1991
Copy link
Author

It looks like the annotation processor isn't generating the $InterceptedDefinition classes. The regular $HelloController$Definition class etc. are being generated, so the annotation processor is running.

@graemerocher
Copy link
Contributor

so Spring is no longer needed for transaction management so this documentation is indeed out of date.

If you do want Spring transaction management I believe you need to add micronaut-spring-annotation to your annotationProcessor classpath

@chrisparton1991
Copy link
Author

Thanks, I'd be more than happy to use Miconaut's transaction management and remove Spring.

Is there a particular annotation/dependency required to use Micronaut transactions for a plain JDBC project? I can only see Spring-based docs in the hibernate-sql guide.

Today I was able to get Spring transactions working in a v2->v3 project migration so it's no longer urgent for me.

@matt-snider
Copy link

I'm guessing this is pretty straightforward to answer and close this issue. I'm wondering the same thing.

so Spring is no longer needed for transaction management so this documentation is indeed out of date.

If you do want Spring transaction management I believe you need to add micronaut-spring-annotation to your annotationProcessor classpath

@graemerocher I keep seeing similar comments about what to do if you want to use micronaut-spring-annotation but don't see a clear recommendation about how to set this up without it. Could you provide any info? Can jakarta.transaction-api simply be added and @Transactional used?

@graemerocher
Copy link
Contributor

@matt-snider This PR seems to address this issue #557

@matt-snider
Copy link

@graemerocher But again, that shows how to set up transactions with Spring. Is it not possible without?

@graemerocher
Copy link
Contributor

If you don't want to use Spring then just add javax.transaction.Transactional. Currently we haven't moved the the jakarta namespace for this. A correctly configured project can be found in the guides https://guides.micronaut.io/latest/micronaut-data-jdbc-repository.html

@graemerocher
Copy link
Contributor

@matt-snider
Copy link

@graemerocher Thanks so much. Both of those examples are for micronaut-data though. I think OP and I are both talking about using just micronaut-sql. But I assume your comment still holds true

If you don't want to use Spring then just add javax.transaction.Transactional.

@graemerocher graemerocher transferred this issue from micronaut-projects/micronaut-core Feb 11, 2022
@graemerocher
Copy link
Contributor

@burtbeckwith could you add some docs on using Micronaut SQL with Micronaut TX without Micronaut Data to address this issue.

@matt-snider
Copy link

@graemerocher @burtbeckwith Very much appreciated 🙏

@viniciusxyz
Copy link
Contributor

Some of these problems were reported in issue #555, in which case I sent an MR with the correction of part of the mentioned problems.

@matt-snider
Copy link

@burtbeckwith Do you have any guidance here? Haven't found a way to get @Transactional to work with or without micronaut-data. Is there a minimal project that shows this working?

@matt-snider
Copy link

Okay I've been struggling with this one for awhile and it turns out the TransactionalInterceptor has been getting applied the whole time. The issue is that any methods not annotated with @Transactional throw an exception and this lead me to believe something was very wrong with my setup.


Unexpected error occurred: No current transaction present. Consider declaring @Transactional on the surrounding method
io.micronaut.transaction.exceptions.NoTransactionException: No current transaction present. Consider declaring @Transactional on the surrounding method
	at io.micronaut.transaction.jdbc.TransactionalConnectionInterceptor.intercept(TransactionalConnectionInterceptor.java:65)
       // omitted
Caused by: io.micronaut.transaction.jdbc.exceptions.CannotGetJdbcConnectionException: No current JDBC Connection found. Consider wrapping this call in transactional boundaries.
	at io.micronaut.transaction.jdbc.DataSourceUtils.doGetConnection(DataSourceUtils.java:135)
	at io.micronaut.transaction.jdbc.DataSourceUtils.getConnection(DataSourceUtils.java:93)

So obviously I'm doing something wrong here because the Transactions Guide doesn't mention anything about all methods requiring the annotation (that wouldn't make sense?), In fact it even says:

You can simply declare a method as transactional with the javax.transaction.Transactional annotation.

You can see the TestController in a repository I created to exemplify the issue

@matt-snider
Copy link

I was able to get transactions working without Spring by adding the dependencies
annotationProcessor("io.micronaut.data:micronaut-data-processor:3.2.2") and implementation("io.micronaut.data:micronaut-data-tx"). It turns out that the NoTransactionException was caused by a bug which I reported in #1399

This issue was about outdated docs, so I hope I didn't derail the discussion too much. Still I wonder if the documentation should be improved here. There is a main section under JDBC about how to use Spring Transactions, but no such section about how to add Micronaut Transactions. Unless there is some reason micronaut-sql + micronaut-data-tx are not recommend together, I think we should document this more clearly, otherwise most users will probably just set up Spring Transactions.

@morki
Copy link
Contributor

morki commented Jul 1, 2022

For me, personally, it was also confusing the first time, because we don't use micronaut-data but need the micronaut-data-tx to use with micronaut-sql. Maybe the transactions module should be transfered to micronaut-sql the same as is the reactive transactions module located in micronaut-r2dbc?

@matt-snider
Copy link

I just ran into this again because I was trying to get JOOQ set up properly such that I have the JooqExceptionTranslator and Transaction Manager from Spring but it doesn't seem to work. It seems like I get proper exception messages with compileOnly("org.springframework:spring-jdbc") but then I don't have the transaction manager, and with runtimeOnly("org.springframework:spring-jdbc") the transaction manager works but not the informative exceptions.

I think what I will try is to remove Spring Transaction management and switch to Micronaut and then implement my own JOOQ exception handler.

I think the documentation would be more clear with a subsection in JOOQ explaining how to set up Transaction management for each scenario (with Spring, without Spring) as well as how to get the JooqExceptionTranslator working properly

@MT-Jacobs
Copy link
Contributor

This documentation is definitely missing. I'm currently trying to read through some tests that use transactions in this project; if the transactions work in the test, then the build.gradle must sufficiently add the right dependencies for transactions to work.

@MT-Jacobs
Copy link
Contributor

MT-Jacobs commented Jul 5, 2023

Looks like, at minimum, you need to add:

io.micronaut.data:micronaut-data-processor
io.micronaut.data:micronaut-data-tx

So, for Kotlin, assuming hikari:

dependencies {
	kapt("io.micronaut.data:micronaut-data-processor")
	implementation("io.micronaut.data:micronaut-data-tx")
        implementation("io.micronaut.data:micronaut-data-tx-jdbc")
	implementation("io.micronaut.sql:micronaut-jdbi")
	runtimeOnly("io.micronaut.sql:micronaut-jdbc-hikari")
}

In short, you must include some Micronaut Data dependencies to get transaction management working in Micronaut SQL if you're not using Micronaut Spring.

@MT-Jacobs
Copy link
Contributor

Oh interesting! So Spring support was recently removed:
#947
which makes documenting how to support transaction management even more important.

@MT-Jacobs
Copy link
Contributor

The documentation is still out of date. Regrettably, it looks like Micronaut 4 has made the docs even more out of date - my instructions are no longer accurate.

Can we have someone with a bit more Micronaut SQL expertise provide some direction on how to properly use transactions when not using Micronaut Data, assuming that's still supported?

@MT-Jacobs
Copy link
Contributor

MT-Jacobs commented Dec 18, 2023

Here's the new dependency that's now needed:

implementation("io.micronaut.data:micronaut-data-tx-jdbc")

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

No branches or pull requests

7 participants