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 <javascript:>> 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 
> <javascript:> 
> > 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 <javascript:> 
> > 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 <javascript:>. 
> > 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.

Reply via email to