Skip to content

Instantly share code, notes, and snippets.

@edoloughlin
Created December 30, 2010 21:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edoloughlin/760295 to your computer and use it in GitHub Desktop.
Save edoloughlin/760295 to your computer and use it in GitHub Desktop.
(ns my.util.sql
(:use clojure.contrib.condition)
(:require
[clojure.contrib.sql :as sql]
[clj-record.core :as rec]
[my.util.error :as err]))
(def *transaction-error* nil) ; While a transaction-wrapper is running, bound to the last error message set by rollback-with-raise
(defn rollback-with-raise
"Call within a transaction body to rollback the transaction and raise a condition
with the related error-code"
[error-code]
(println "ROLLING BACK: " error-code)
(set! *transaction-error* error-code)
(sql/set-rollback-only))
(defmacro transaction
"Execute body in a clj-record transaction. rollback-with-raise may be called in body and will
rollback the transaction and raise a condition with the specified error-code"
[db-spec & body]
`(binding [my.util.sql/*transaction-error* nil]
(try
(let [tx-result# (rec/transaction ~db-spec ~@body)]
(if-not (nil? *transaction-error*)
(err/raise-with-message *transaction-error*))
tx-result#)
(catch Exception e#
(println "CAUGHT: " e#)
(if-not (nil? *transaction-error*)
(err/raise-with-message *transaction-error*)
(err/raise-with-message :transaction-wrapper-error e#))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment