Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/marschall/jfr-jdbctemplate
an implementation of Spring JdbcTemplate that generates Flight Recorder events
https://github.com/marschall/jfr-jdbctemplate
java-flight-recorder jdbctemplate spring-jdbctemplate
Last synced: about 1 month ago
JSON representation
an implementation of Spring JdbcTemplate that generates Flight Recorder events
- Host: GitHub
- URL: https://github.com/marschall/jfr-jdbctemplate
- Owner: marschall
- Created: 2018-12-07T08:14:28.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-07-13T05:24:32.000Z (over 1 year ago)
- Last Synced: 2023-07-26T21:59:59.555Z (over 1 year ago)
- Topics: java-flight-recorder, jdbctemplate, spring-jdbctemplate
- Language: Java
- Size: 559 KB
- Stars: 3
- Watchers: 4
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
JFR JdbcTemplate [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.marschall/jfr-jdbctemplate/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.marschall/jfr-jdbctemplate) [![Javadocs](https://www.javadoc.io/badge/com.github.marschall/jfr-jdbctemplate.svg)](https://www.javadoc.io/doc/com.github.marschall/jfr-jdbctemplate)
================An implementation of Spring [JdbcTemplate](https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#jdbc) that generates [Flight Recorder](https://openjdk.java.net/jeps/328) events.
This project requires Java 11 based on OpenJDK or later.
```xml
com.github.marschall
jfr-jdbctemplate
2.0.0```
Versions 1.x are intended for Spring 5.x / Java 11, versions 2.x are intended for Spring 6.x / Java 17.
![Flight Recording of a JUnit Test](https://github.com/marschall/jfr-jdbctemplate/raw/master/src/main/javadoc/resources/Screenshot%20from%202019-05-13%2021-09-33.png)
Compared to approaches based on `DataSource` an approach based on `JdbcTemplate` has the advantage that it captures a complete database interaction. For example if you process many rows the initial `PreparedStatement#execute()` might be fast but most of the time may be spent in `ResultSet#next()`. A `JdbcTemplate` based approach generates a single JFR event for the entire interaction that involves several JDBC method invocations.
Spring Class | JFR Class |
|-------------------------------------------------------------------------|------------------------------------------------------------------------|
| `org.springframework.jdbc.core.JdbcOperations` | `com.github.marschall.jfr.jdbctemplate.JfrJdbcOperations` |
| `org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations` | `com.github.marschall.jfr.jdbctemplate.JfrNamedParameterJdbcOperations` |Reported Attributes
-------------------
- operationName
- The name of the execute JDBC operation, this corresponds to the method name on
JdbcOperations
/JdbcTemplate
. - query
- The SQL query string passed to the JDBC driver. May be missing especially if custom
org.springframework.jdbc.core.PreparedStatementCreator
fail to implementorg.springframework.jdbc.core.SqlProvider
. - rowCount
- In the case of a
SELECT
the number of rows returned. In the case of anUPDATE
orDELETE
the number of rows affected.-1
for a statement that does not return anything like a DDL.-2
when no information about the number of rows is available.
Overhead
--------
We try to keep overhead to a minimum and have no additional allocations besides the JFR events. Besides the overhead of the event the only additional overhead is:
* a wrapper around `JdbcTemplate`
* a few `instanceof` operations and casts
* a `finally` block
* a capturing lambda for `#queryForStream` methods to record `Stream#close` as the end time of the event
* a small wrapper around every `RowCallbackHandler`
We assume `org.springframework.jdbc.core.SqlProvider#getSql()` is a simple getter.
Usage
-----
```java
@Configuration
public class JdbcConfiguration {
@Autowired
private DataSource dataSource;
@Bean
public JdbcOperations jdbcOperations() {
return new JfrJdbcOperations(new JdbcTemplate(this.dataSource));
}
@Bean
public NamedParameterJdbcOperations namedParameterJdbcOperations() {
return new JfrNamedParameterJdbcOperations(new NamedParameterJdbcTemplate(this.jdbcOperations()));
}
}
```
You need something like the following JVM options to run Flight Recorder
```
-XX:StartFlightRecording:filename=recording.jfr
-XX:FlightRecorderOptions:stackdepth=128
```
Limitations
-----------
* When the SQL query is not provided as a `String` but as a `PreparedStatementCreator` or `CallableStatementCreator` it has to implement `SqlProvider` for the query string to show up in the flight recording.
* `JdbcTemplate#query(PreparedStatementCreator, PreparedStatementSetter, ResultSetExtractor)` is not available because it is defined on `JdbcTemplate` and not `JdbcOperations`.
* Several spring-jdbc classes `AbstractJdbcCall`, `SimpleJdbcCall`, `StoredProcedure`, `RdbmsOperation`, `AbstractJdbcInsert`, `SimpleJdbcInsert` but also `JdbcTestUtils` and `JdbcBeanDefinitionReader` require a `JdbcTemplate` and do not work with `JdbcOperations`. We have a [pull request](https://github.com/spring-projects/spring-framework/pull/23066/files) open for this but it has not been merged yet.
* `JdbcOperations#execute(ConnectionCallback)` can not provide any insight into what is executed inside, that would require integration with [marschall/jfr-jdbc](https://github.com/marschall/jfr-jdbc)