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.med...@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 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.

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