(if it's just a regular ThreadLocal, you should be able to get its value through (.get tx))
To elucidate briefly, I mean something like this: (def ^:dynamic *tx*) ;; elsewhere (binding [*tx* (.get tx)] ...do stuff ...cleanup) a with-tx macro would make this pattern reusable throughout your code. On Wednesday, March 4, 2015 at 1:43:36 PM UTC-5, adrian...@mail.yu.edu wrote: > > Ah I think I understand now! Is it possible to dereference the connection > and "hold on" to the thread local state? If so, then dynamically binding > the transactional connection and doing all of your work within that context > might be a good solution. You can also write a macro to do this, > closing/doing cleanup of the connection before exiting the dynamic scope of > your transaction. > > On Wednesday, March 4, 2015 at 1:15:02 PM UTC-5, Colin Yates wrote: >> >> Hi Adrian, and thanks for replying. >> >> I understand your point, but the subtlety is that a transactional >> connection is per function invocation where as the database component >> is per Component lifecycle - passing the db around isn't sufficient >> here. >> >> Spring plumbing binds a transactional connection to a thread local and >> then passes a connection proxy around - accessing that proxy magically >> (through the use of the lovely AOP) resolves to the current >> thread-local transactional connection. >> >> I don't see any option other than to re-implement that in Clojure or >> pass an explicit 'unit-of-work' around but it all feels wrong in >> Clojure. >> >> The problem at the moment is that the implementation of each protocol >> will execute in separate transactions. >> >> >> >> >> On 4 March 2015 at 18:06, <adrian...@mail.yu.edu> wrote: >> > Having never used Spring (or anything else resembling the style of code >> you >> > presented) I don't really know if I'm understanding what you're asking. >> > >> > However, it might be useful to wrap your database in a component. I do >> this >> > for Datomic all of the time, and the boilerplate looks something like >> this: >> > https://gist.github.com/aamedina/a1ca5e97c1a5d73fe141. I'm not sure >> exactly >> > how this would fit into JDBC, but I'm sure you can figure it out if you >> > think it would be worthwhile. >> > >> > I then pass the database component to any other component in my system >> that >> > I know will make use of it. If used in a middleware-like scenario >> (where an >> > arbitrary function is passed to the component, possibly composed with >> other >> > functions, and invoked elsewhere), I usually have a convention where I >> pass >> > a map of options as an argument to the handler, and make the database a >> > value in that map. >> > >> > >> > On Wednesday, March 4, 2015 at 12:58:58 PM UTC-5, Colin Yates wrote: >> >> >> >> Hi, >> >> >> >> I am looking for the Clojure equivalent of: >> >> >> >> class Whatever { >> >> @Transactional >> >> void doSomething(IDoSomething one, IDoSomethingElse two) { >> >> one.doSomething() >> >> two.doSomething() >> >> } >> >> } >> >> >> >> where both one and two are dependency injected with a proxy which >> resolves >> >> to a thread local database connection. In addition, one might itself >> have a >> >> collaborator which itself has a collaborator which needs a datasource. >> >> >> >> So far I have two protocols: >> >> >> >> (defprotocol IDoSomething >> >> (do-something [this ...]) >> >> >> >> (defprotocol IDoSomethingElse >> >> (do-something [this ...]) >> >> >> >> Each protocol may have a number of implementations, one of which is a >> JDBC >> >> implementation: >> >> >> >> (defrecord JdbcIDoSomething [db] >> >> (do-something [this ...] ...)) >> >> >> >> The problem is that the calling code only gets provided an >> IDoSomething >> >> and an IDoSomethingElse and it wants to do something like: >> >> >> >> (let [one (->JdbcDoSomething db) two (->JdbcDoSomethingElse db)] >> >> (with-transaction [tx db] >> >> (do-something one) >> >> (do-something-else two))) >> >> >> >> The problem here is that the implementations of do-something and >> >> do-something-else won't have access to the local bound 'tx', they will >> have >> >> their own 'db'. >> >> >> >> I realise the general argument is to be explicit and pass a db as the >> >> first argument to the protocol but this isn't appropriate in this case >> as >> >> there are validly multiple implementations. I could abstract a >> >> 'unit-of-work' and pass that as the first argument to the protocols >> but that >> >> seems a bit painful. >> >> >> >> Also, these protocols may be used quite far away from where the >> database >> >> code lives and passing a parameter all the way through the call stack >> is >> >> painful. >> >> >> >> I am using Stuart Sierra's components if that makes any difference. >> >> >> >> I can't be the first person to run into this but google is >> surprisingly >> >> unhelpful which makes me think I have missed something fundamental, >> and that >> >> I have something upside down. >> >> >> >> What do you all do? >> >> >> >> >> > -- >> > You received this message because you are subscribed to the Google >> > Groups "Clojure" group. >> > To post to this group, send email to clo...@googlegroups.com >> > Note that posts from new members are moderated - please be patient with >> your >> > first post. >> > To unsubscribe from this group, send email to >> > clojure+u...@googlegroups.com >> > For more options, visit this group at >> > http://groups.google.com/group/clojure?hl=en >> > --- >> > You received this message because you are subscribed to the Google >> Groups >> > "Clojure" group. >> > To unsubscribe from this group and stop receiving emails from it, send >> an >> > email to clojure+u...@googlegroups.com. >> > For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.