(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.

Reply via email to