sql

All things SQL and JDBC...
Ashwin Bhaskar 2020-11-03T06:33:43.200700Z

I am using next.jdbc. I get the error Could not locate clojure/datafy__init.class or clojure/datafy.clj on classpath., compiling:(next/jdbc/result_set.clj:1:1) when I import [next.jdbc.sql :as sql]]

seancorfield 2020-11-03T17:43:45.207200Z

The second sentence of Getting Started is "It is designed to work with Clojure 1.10 or later" -- sounds like I need to make it clearer that is a requirement.

seancorfield 2020-11-03T17:47:11.207400Z

I updated the installation notes on the Getting Started page: https://github.com/seancorfield/next-jdbc/blob/develop/doc/getting-started.md#installation

Ashwin Bhaskar 2020-11-03T06:34:30.200900Z

could not find anyone facing this with a simple google search

dpsutton 2020-11-03T06:38:35.201100Z

next.jdbc requires clojure 1.10 i believe. in your deps.edn/project.clj file you can add a dependency on org.clojure/clojure "1.10.1" or org.clojure/clojure {:mvn/version "1.10.1"} depending on which deps manager you are using

Ashwin Bhaskar 2020-11-03T06:39:42.201300Z

oh okay..let me try that out

Ashwin Bhaskar 2020-11-03T06:41:18.201500Z

@dpsutton thanks. yes, that seems to have solved the issue. Can I ask what made you suspect that it was the clojure version mismatch?

dpsutton 2020-11-03T06:47:37.201800Z

because clojure/datafy.clj was introduced in clojure 1.10. as its in the core language and a recent addition, there aren't too many other possible culprits

dpsutton 2020-11-03T06:48:06.202600Z

next.jdbc needs it and if its not present the language is too old

2020-11-03T06:48:51.203800Z

datafy/nav were added to Clojure ~ 1.10, if you were using an earlier version they wouldn’t be found

Ashwin Bhaskar 2020-11-03T07:16:57.204Z

got it:)

jumar 2020-11-03T13:23:40.205800Z

Is there any real reason to use :read-only? true (clojure.java.jdbc)? More specifically for a single query and MySQL? What about benefits for multiple queries?

synthomat 2020-11-03T16:23:30.206700Z

Has an effect on Transaction locking or how data is fetched on replicated database servers?

Jakub Holý 2020-11-03T17:03:24.206800Z

I guess read javadoc for the MySQL jdbc driver? Notice it does not guarantee that you cannot write to the DB (I believe)

dharrigan 2020-11-03T17:18:33.207Z

Indeed. It's much better, imho, to have a dedicated user for the db that has permissions only to select and connect using that.

seancorfield 2020-11-03T17:49:41.208800Z

@synthomat :read-only? true affects connections (setting them to readonly). There is also a :read-only value for result set concurrency, which is what you are thinking of, maybe?

seancorfield 2020-11-03T17:51:12.208900Z

@jumar The JDBC API docs say that setting a connection to read only is "a hint to the driver to enable database optimizations" but the exact effect is going to be DB-specific I expect.

seancorfield 2020-11-03T17:53:55.209100Z

I've read some suggestions that you need to set the connection read only for some DBs to allow for streaming of large result sets, but that may also be confusion with the result set concurrency which I've also read suggestions that you need to select read only for result sets for that streaming to occur.

seancorfield 2020-11-03T17:54:59.209300Z

If you're just doing simple queries, I wouldn't expect it to make much difference but, as Jakub says, the only way to be more certain is to go digging in the MySQL documentation.

jumar 2020-11-03T20:02:07.209500Z

Thanks everyone. I wanted to check if this is something you commonly do. We have several such queries from a long time ago and nobody is sure why. Based on the MySQL docs, I'd say it doesn't bring anything (specifically for cases when there's just a single select): https://dev.mysql.com/doc/refman/5.6/en/innodb-performance-ro-txn.htmlInnoDB can avoid the overhead associated with setting up the https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_transaction_id (TRX_ID field) for transactions that are known to be read-only. A transaction ID is only needed for a https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_transaction that might perform write operations or https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_locking_read such as SELECT ... FOR UPDATE. Eliminating unnecessary transaction IDs reduces the size of internal data structures that are consulted each time a query or data change statement constructs a https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_read_view. • InnoDB detects read-only transactions when: • The transaction is started with the START TRANSACTION READ ONLY statement. • The autocommit setting is turned on, so that the transaction is guaranteed to be a single statement, and the single statement making up the transaction is a “non-locking” SELECT statement. That is, a SELECT that does not use a FOR UPDATE or LOCK IN SHARED MODE clause. 

seancorfield 2020-11-03T20:35:42.209700Z

Yeah, and there's no JDBC API for directly starting a read only transaction, so using a read only connection in a context where JDBC itself would start a transaction is about the only way to do it, as far as I can tell from the JDBC docs. Auto-commit is turned on by default in JDBC and every operation is wrapped in a transaction by default. I'm still not clear on whether that's sufficient to trigger the InnoDB optimizations tho'...

👍 1