Is it possible to tell programatically if I'm in a transactional context?

27 views
Skip to first unread message

Dave Griffith

unread,
Dec 8, 2008, 5:52:38 PM12/8/08
to Clojure
I gave a small talk on Clojure this afternoon to my team. It went
well, and got the expected oohs and ahhs with respect to the potential
of software transactional memory. One question asked, though, was
about I/O in software transactions. It was clear to everyone why I/O
needed to be prohibitted in transactions, but questions were raised as
to whether there was any way to actually prevent it. Looking through
the API, I couldn't find any way of detecting when execution was
occuring in a transactional context or not.

--Dave Griffith

Stuart Halloway

unread,
Dec 8, 2008, 6:07:46 PM12/8/08
to clo...@googlegroups.com
Hi Dave,

It looks like LockingTransaction.getRunning would need to be made
public. What do you plan to do with it?

As a workaround:

(defn in-tx? [] (try (ensure (ref true)) (catch
IllegalStateException e false)))

Stuart

Dave Griffith

unread,
Dec 8, 2008, 7:44:19 PM12/8/08
to Clojure
The basic use case is as a guard for I/O, to prevent them from from
filling the disk/spamming the network accidentally in case of
transaction live-lock. Probably a bit more paranoia than is idiomatic
in the dynamically-typed world, but there are domains where that's
necessary. The workaround is perfectly fine, although it looks like
exposing a method in LockingTransaction would be more performant.

--Dave Griffith

Rich Hickey

unread,
Dec 11, 2008, 9:32:14 AM12/11/08
to Clojure


On Dec 8, 7:44 pm, Dave Griffith <dave.l.griff...@gmail.com> wrote:
> The basic use case is as a guard for I/O, to prevent them from from
> filling the disk/spamming the network accidentally in case of
> transaction live-lock. Probably a bit more paranoia than is idiomatic
> in the dynamically-typed world, but there are domains where that's
> necessary. The workaround is perfectly fine, although it looks like
> exposing a method in LockingTransaction would be more performant.
>

I've added io! blocks, which will throw an exception when run in a
transaction:

(dosync (io! 42))
-> java.lang.IllegalStateException: I/O in transaction (NO_SOURCE_FILE:
0)

They take an optional string which will serve as the exception text:

(dosync (io! "bad" 42))
-> java.lang.IllegalStateException: bad (NO_SOURCE_FILE:0)

await and await-for now contain io! blocks.

Rich


>
> On Dec 8, 6:07 pm, Stuart Halloway <stuart.hallo...@gmail.com> wrote:
>
> > Hi Dave,
>
> > It looks like LockingTransaction.getRunning would need to be made
> > public. What do you plan to do with it?
>
> > As a workaround:
>
> > (defn in-tx? [] (try (ensure (ref true)) (catch
> > IllegalStateException e false)))
>
> > Stuart
>
> > > I gave a small talk on Clojure this afternoon to my team. It went
> > > well, and got the expected oohs and ahhs with respect to the potential
> > > of software transactional memory. One question asked, though, was
> > > about I/O in softwaretransactions. It was clear to everyone why I/O
> > > needed to be prohibitted intransactions, but questions were raised as

Dave Griffith

unread,
Dec 11, 2008, 9:51:51 AM12/11/08
to Clojure
Excellent! This is a great way of making code fail-fast for a class of
bugs that would normally only occur under load (i.e. at the worst
possible time).

--Dave Griffith
Reply all
Reply to author
Forward
0 new messages