This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-08-11
Channels
- # announcements (8)
- # beginners (17)
- # boot (1)
- # cider (20)
- # cljdoc (7)
- # cljs-dev (14)
- # clojure (62)
- # clojure-dev (16)
- # clojure-hamburg (1)
- # clojure-russia (2)
- # clojure-spec (22)
- # clojure-uk (15)
- # clojurebridge (1)
- # clojurescript (23)
- # core-async (4)
- # core-logic (17)
- # cursive (2)
- # datomic (4)
- # duct (1)
- # figwheel-main (40)
- # fulcro (15)
- # leiningen (1)
- # off-topic (27)
- # re-frame (3)
- # shadow-cljs (9)
- # specter (3)
- # sql (59)
If you don't use with-db-transaction
, then each individual SQL statement is automatically wrapped in its own transaction (and therefore succeeds or fails on its own).
@seancorfield how to use it with Hikari-CP?
Your db spec is just a map containing :datasource
for that use case.
(j/with-db-connection [conn {:datasource (:db-pool sistema)}]
(j/with-db-transaction [tx conn]
(j/db-set-rollback-only! tx)
(j/insert! tx :ven_pedido_vendedor {:cod_vendedor "1" :cod_cliente "000000" :cod_loja "01"})
))
?@fabrao Have you read the java.jdbc
docs about transactions? http://clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html#using-transactions
You seem to be doing it in that code fragment...
I assume (:db-pool sistema)
is your HikariCP connectionpool object?
Yeah, I was about to point that out -- that insert!
will always be rolled back.
The connection pool is irrelevant for with-db-transaction
and with-db-connection
tho' -- they don't care, they just check if the db spec they are passed contains an active connection and if it doesn't they call get-connection
on it and add that in.
{:datasource (some-pool)}
is just a regular db spec, just like {:dbtype "..." :dbname "..." ...}
the get/close operations are still called on both -- with the former, that gets a connection from the pool and returns it; with the latter, it opens a new connection and closes it.
The connection pool semantics are completely orthogonal to how java.jdbc
works.
But, yeah, if you want to execute a whole bunch of functions within the same transaction, you'll need with-db-transaction
and then pass the t-conn
binding into them (as a new db spec).
Transactions are also somewhat orthogonal to everything else in java.jdbc
-- if you pass a db spec with an open connection and an active transaction, that's what will be used; if you pass a db spec with an open connection and no transaction, each op will be done in a fresh transaction; if you pass a db spec with no connection, each op will be done in a fresh connection and in a fresh transaction.
So the calling code controls how the operations behave.
(but bear in mind java.jdbc
doesn't nest transactions -- if you try to use transactions inside an active transaction, those nested transaction boundaries are ignored and everything happens inside a single, top-level transaction)
You only need with-db-connection
if you are planning to run multiple operations on a single connection.
s/poll/pool/
Otherwise people will think you're polling the database -- making multiple queries to see if the state has changed 🙂
You shouldn't nest with-db-transaction
/ with-db-connection
calls -- so having them inside low-level operations is a bad idea.
so, I intend to use rollback because some businnes rules can fail, and I don´t want to delete the inserts before
I should probably make it safe to nest with-db-connection
calls... I'll open a JIRA ticket.
in that case of using some->
(some-> <data> rule1 rule2 rule3)
, what is the best way to do this?https://dev.clojure.org/jira/browse/JDBC-171 to allow nested with-db-connection
calls to be safe...
The fix for this will be in 0.7.8 🙂
@fabrao what is <data>
? how do your functions get passed the db-spec
to operate on?
Ah, so you're relying on mutable global state?
And each of your ruleN
functions reaches out to that global state to get a db connection?
If I will use some->
I have to change the rule for using (defn rule1 [tx par1 par2] ...)
Use some->>
and then the "data" parameter will be the last argument and you can just do
(j/with-db-transaction [t-conn db-spec]
(some->> <data>
(rule1 t-conn)
(rule2 t-conn param1)
(rule3 t-conn)))
(or else, to use some->
, your "data" could always be first but then your rules will have signatures like [data tx par1 par2]
which seems weird)
Just be consistent 🙂
The fix for this will be in 0.7.8 🙂