X-Git-Url: http://git.kpe.io/?p=clsql.git;a=blobdiff_plain;f=sql%2Ftransactions.cl;h=c95e8c307501fd368049b48623af48401658b242;hp=6b980aa860e6638c4ebc1ee1be3ccc7faac9642d;hb=998937376fa6f9ce29bd3c7954fb0ebca91c37d7;hpb=47d0d4e375f432000f780f95371cb0c32fab9712 diff --git a/sql/transactions.cl b/sql/transactions.cl index 6b980aa..c95e8c3 100644 --- a/sql/transactions.cl +++ b/sql/transactions.cl @@ -4,13 +4,12 @@ ;;;; ;;;; Name: transactions.cl ;;;; Purpose: Transaction support -;;;; Programmers: Kevin M. Rosenberg, Marc Battyani +;;;; Programmers: Marc Battyani ;;;; Date Started: Apr 2002 ;;;; -;;;; $Id: transactions.cl,v 1.2 2002/05/07 10:19:13 marc.battyani Exp $ +;;;; $Id: transactions.cl,v 1.7 2002/09/17 17:16:43 kevin Exp $ ;;;; ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg -;;;; and Copyright (c) 2000-2002 by onShore Development ;;;; ;;;; CLSQL users are granted the rights to distribute and use this software ;;;; as governed by the terms of the Lisp Lesser GNU Public License @@ -25,10 +24,10 @@ (defclass transaction () ((commit-hooks :initform () :accessor commit-hooks) (rollback-hooks :initform () :accessor rollback-hooks) - (aborted :initform nil :accessor aborted))) + (status :initform nil :accessor status))) ;can be nil :rolled-back or :commited (defmethod database-start-transaction ((database closed-database)) - (signal-closed-database-error database)) + (error 'clsql-closed-database-error database)) (defmethod database-start-transaction (database) (unless (transaction database) @@ -37,52 +36,50 @@ (let ((transaction (transaction database))) (setf (commit-hooks transaction) nil (rollback-hooks transaction) nil - (aborted transaction) nil) + (status transaction) nil) (execute-command "BEGIN" :database database)))) -(defmethod database-end-transaction ((database closed-database) commit) - (signal-closed-database-error database)) +(defmethod database-end-transaction ((database closed-database)) + (error 'clsql-closed-database-error database)) -(defmethod database-end-transaction (database commit) - (when (not commit) - (setf (aborted (transaction database)) t)) +(defmethod database-end-transaction (database) (if (> (transaction-level database) 0) (when (zerop (decf (transaction-level database))) (let ((transaction (transaction database))) - (if (aborted transaction) - (unwind-protect - (execute-command "ROLLBACK" :database database) - (map nil #'funcall (rollback-hooks database))) + (if (eq (status transaction) :commited) (progn (execute-command "COMMIT" :database database) - (map nil #'funcall (commit-hooks transaction)))))) + (map nil #'funcall (commit-hooks transaction))) + (unwind-protect ;status is not :commited + (execute-command "ROLLBACK" :database database) + (map nil #'funcall (rollback-hooks transaction)))))) (warn "Continue without commit." 'clsql-simple-error :format-control "Cannot commit transaction against ~A because there is no transaction in progress." :format-arguments (list database)))) -(defun abort-transaction (database) - (when (transaction database) - (setf (aborted (transaction database)) t))) +(defun rollback-transaction (database) + (when (and (transaction database)(not (status (transaction database)))) + (setf (status (transaction database)) :rolled-back))) + +(defun commit-transaction (database) + (when (and (transaction database)(not (status (transaction database)))) + (setf (status (transaction database)) :commited))) -(defun add-transaction-commit-hook (database abort-hook) +(defun add-transaction-commit-hook (database commit-hook) (when (transaction database) - (push abort-hook (abort-hooks (transaction database))))) + (push commit-hook (commit-hooks (transaction database))))) (defun add-transaction-rollback-hook (database rollback-hook) (when (transaction database) (push rollback-hook (rollback-hooks (transaction database))))) -(defmacro with-transaction ((&key (database '*default-database*) abort-function) - &rest body) - (let ((db (gensym "db")) - (commit (gensym "commit-"))) - `(let ((,db ,database) - (,commit nil)) +(defmacro with-transaction ((&key (database '*default-database*)) &rest body) + (let ((db (gensym "db-"))) + `(let ((,db ,database)) (unwind-protect - (progn - (database-start-transaction ,db) - (setf ,commit t) - ,@body - (setf ,commit nil)) - (database-end-transaction ,db ,commit))))) + (progn + (database-start-transaction ,db) + ,@body + (commit-transaction ,db)) + (database-end-transaction ,db)))))