Update of /project/elephant/cvsroot/elephant/src/db-bdb
In directory clnet:/tmp/cvs-serv3271/src/db-bdb
Modified Files:
bdb-collections.lisp bdb-controller.lisp bdb-slots.lisp
bdb-transactions.lisp berkeley-db.lisp
Log Message:
Large changeset to enable thread safety; more *auto-commit* removal; sql class-root fix; new transaction model; cleaned up defaults for *store-controller*
--- /project/elephant/cvsroot/elephant/src/db-bdb/bdb-collections.lisp 2007/02/01 15:19:49 1.13
+++ /project/elephant/cvsroot/elephant/src/db-bdb/bdb-collections.lisp 2007/02/02 23:51:58 1.14
@@ -110,14 +110,14 @@
(defmethod build-btree-index ((sc bdb-store-controller) &key primary key-form)
(make-instance 'bdb-btree-index :primary primary :key-form key-form :sc sc))
-(defmethod add-index ((bt bdb-indexed-btree) &key index-name key-form populate)
+(defmethod add-index ((bt bdb-indexed-btree) &key index-name key-form (populate t))
(let ((sc (get-con bt)))
;; Setting the value of *store-controller* is unfortunately
;; absolutely required at present, I think because the copying
;; of objects is calling "make-instance" without an argument.
;; I am sure I can find a way to make this cleaner, somehow.
(if (and (not (null index-name))
- (symbolp index-name)
+ (symbolp index-name)
(or (symbolp key-form) (listp key-form)))
;; Can it be that this fails?
(let ((ht (indices bt))
--- /project/elephant/cvsroot/elephant/src/db-bdb/bdb-controller.lisp 2007/02/01 04:03:26 1.19
+++ /project/elephant/cvsroot/elephant/src/db-bdb/bdb-controller.lisp 2007/02/02 23:51:58 1.20
@@ -62,7 +62,7 @@
;;
(defmethod open-controller ((sc bdb-store-controller) &key (recover nil)
- (recover-fatal nil) (thread t) (errfile nil)
+ (recover-fatal nil) (thread t) ;; (errfile nil)
(deadlock-detect nil))
(let ((env (db-env-create)))
(setf (controller-environment sc) env)
@@ -158,7 +158,7 @@
"Get the next OID."
(declare (type bdb-store-controller sc))
(db-sequence-get-fixnum (controller-oid-seq sc) 1 :transaction +NULL-VOID+
- :auto-commit t :txn-nosync t))
+ :txn-nosync t))
;;
;; Automated Deadlock Support
--- /project/elephant/cvsroot/elephant/src/db-bdb/bdb-slots.lisp 2007/01/22 22:22:35 1.1
+++ /project/elephant/cvsroot/elephant/src/db-bdb/bdb-slots.lisp 2007/02/02 23:51:58 1.2
@@ -23,8 +23,9 @@
;; Persistent slot protocol implementation
;;
+(declaim #-elephant-without-optimize (optimize (speed 3) (safety 1) (space 0)))
+
(defmethod persistent-slot-reader ((sc bdb-store-controller) instance name)
-;; (declare (optimize (speed 3) (safety 1) (space 1)))
(with-buffer-streams (key-buf value-buf)
(buffer-write-int (oid instance) key-buf)
(serialize name key-buf sc)
@@ -37,20 +38,16 @@
(error 'unbound-slot :instance instance :name name)))))
(defmethod persistent-slot-writer ((sc bdb-store-controller) new-value instance name)
-;; (declare (optimize (speed 3) (safety 1) (space 1)))
-;; (format t "psw -- sc: ~A ct: ~A ac: ~A~%" *store-controller* *current-transaction* *auto-commit*)
(with-buffer-streams (key-buf value-buf)
(buffer-write-int (oid instance) key-buf)
(serialize name key-buf sc)
(serialize new-value value-buf sc)
(db-put-buffered (controller-db sc)
key-buf value-buf
- :transaction *current-transaction*
- :auto-commit *auto-commit*)
+ :transaction (txn-default *current-transaction*))
new-value))
(defmethod persistent-slot-boundp ((sc bdb-store-controller) instance name)
-;; (declare (optimize (speed 3) (safety 1) (space 1)))
(with-buffer-streams (key-buf value-buf)
(buffer-write-int (oid instance) key-buf)
(serialize name key-buf sc)
@@ -59,10 +56,8 @@
(if buf t nil))))
(defmethod persistent-slot-makunbound ((sc bdb-store-controller) instance name)
-;; (declare (optimize (speed 3) (safety 1) (space 1)))
(with-buffer-streams (key-buf)
(buffer-write-int (oid instance) key-buf)
(serialize name key-buf sc)
(db-delete-buffered (controller-db sc) key-buf
- :transaction *current-transaction*
- :auto-commit *auto-commit*)))
+ :transaction (txn-default *current-transaction*))))
--- /project/elephant/cvsroot/elephant/src/db-bdb/bdb-transactions.lisp 2006/11/11 18:41:10 1.4
+++ /project/elephant/cvsroot/elephant/src/db-bdb/bdb-transactions.lisp 2007/02/02 23:51:58 1.5
@@ -21,11 +21,10 @@
(defmethod execute-transaction ((sc bdb-store-controller) txn-fn
&key
- transaction environment parent
- (retries 100) degree-2
- dirty-read txn-nosync txn-nowait txn-sync)
- (let ((env (if environment environment
- (controller-environment sc))))
+ transaction parent environment
+ (retries 100)
+ degree-2 dirty-read txn-nosync txn-nowait txn-sync)
+ (let ((env (if environment environment (controller-environment sc))))
(loop
for count fixnum from 1 to retries
for success of-type boolean = nil
@@ -33,7 +32,7 @@
(let ((txn
(if transaction transaction
(db-transaction-begin env
- :parent parent
+ :parent (if parent parent +NULL-VOID+)
:degree-2 degree-2
:dirty-read dirty-read
:txn-nosync txn-nosync
@@ -42,20 +41,17 @@
(declare (type pointer-void txn)
(dynamic-extent txn))
(let ((result
- (let ((*current-transaction* txn)
- (*auto-commit* nil))
- (declare (special *current-transaction* *auto-commit*))
-;; (dynamic-extent *current-transaction* *auto-commit*))
+ (let ((*current-transaction* txn))
+ (declare (special *current-transaction*))
(catch 'transaction
(unwind-protect
(prog1
(funcall txn-fn)
(setq success t)
- (db-transaction-commit :transaction txn
- :txn-nosync txn-nosync
- :txn-sync txn-sync))
+ (db-transaction-commit txn :txn-nosync txn-nosync
+ :txn-sync txn-sync))
(unless success
- (db-transaction-abort :transaction txn)))))))
+ (db-transaction-abort txn)))))))
(unless (and (eq result txn) (not success))
(return result))))
finally (error "Too many retries in transaction"))))
@@ -79,6 +75,7 @@
dirty-read
degree-2
&allow-other-keys)
+ (assert (not *current-transaction*))
(db-transaction-begin (controller-environment sc)
:parent parent
:txn-nosync txn-nosync
@@ -88,8 +85,101 @@
:degree-2 degree-2))
-(defmethod controller-commit-transaction ((sc bdb-store-controller) &key transaction &allow-other-keys)
- (db-transaction-commit :transaction transaction))
+(defmethod controller-commit-transaction ((sc bdb-store-controller) transaction &key &allow-other-keys)
+ (assert (not *current-transaction*))
+ (db-transaction-commit transaction))
-(defmethod controller-abort-transaction ((sc bdb-store-controller) &key &allow-other-keys)
- (db-transaction-abort))
\ No newline at end of file
+(defmethod controller-abort-transaction ((sc bdb-store-controller) transaction &key &allow-other-keys)
+ (assert (not *current-transaction*))
+ (db-transaction-abort transaction))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Old versions of with-transaction
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+#|
+(defmacro with-transaction ((&key transaction environment
+ (parent '*current-transaction*)
+ (retries 100)
+ dirty-read read-uncommitted
+ txn-nosync txn-nowait txn-sync)
+ &body body)
+ (let ((txn (if transaction transaction (gensym)))
+ (count (gensym))
+ (result (gensym))
+ (success (gensym)))
+ `(loop
+ for ,count fixnum from 1 to ,retries
+ for ,success of-type boolean = nil
+ do
+ (with-alien ((,txn (* t)
+ (db-transaction-begin ,environment
+ :parent ,parent
+ :dirty-read (or ,dirty-read ,read-uncommitted)
+ :txn-nosync ,txn-nosync
+ :txn-nowait ,txn-nowait
+ :txn-sync ,txn-sync)))
+ (let ((,result
+ (let ((*current-transaction* ,txn))
+ (declare (special *current-transaction*)
+ (dynamic-extent *current-transaction*))
+ (catch 'transaction
+ (unwind-protect
+ (prog1 (progn ,@body)
+ (setq ,success t)
+ (db-transaction-commit :transaction ,txn
+ :txn-nosync ,txn-nosync
+ :txn-sync ,txn-sync))
+ (unless ,success
+ (db-transaction-abort :transaction ,txn)))))))
+ (unless (and (eq ,result ,txn) (not ,success))
+ (return ,result))))
+ finally (error "Too many retries"))))
+
+(defmacro with-transaction ((&key transaction environment
+ (parent '*current-transaction*)
+ (retries 100)
+ degree-2 read-committed
+ dirty-read read-uncommitted
+ txn-nosync txn-nowait txn-sync)
+ &body body)
+ "Execute a body with a transaction in place. On success,
+the transaction is committed. Otherwise, the transaction is
+aborted. If the body deadlocks, the body is re-executed in
+a new transaction, retrying a fixed number of iterations."
+ (let ((txn (if transaction transaction (gensym)))
+ (count (gensym))
+ (result (gensym))
+ (success (gensym)))
+ `(loop
+ for ,count fixnum from 1 to ,retries
+ for ,success of-type boolean = nil
+ do
+ (let ((,txn
+ (db-transaction-begin ,environment
+ :parent ,parent
+ :degree-2 (or ,degree-2 ,read-committed)
+ :dirty-read (or ,dirty-read ,read-uncommitted)
+ :txn-nosync ,txn-nosync
+ :txn-nowait ,txn-nowait
+ :txn-sync ,txn-sync)))
+ (declare (type pointer-void ,txn)
+ (dynamic-extent ,txn))
+ (let ((,result
+ (let ((*current-transaction* ,txn))
+ (declare (special *current-transaction*)
+ (dynamic-extent *current-transaction*))
+ (catch 'transaction
+ (unwind-protect
+ (prog1 (progn ,@body)
+ (setq ,success t)
+ (db-transaction-commit :transaction ,txn
+ :txn-nosync ,txn-nosync
+ :txn-sync ,txn-sync))
+ (unless ,success
+ (db-transaction-abort :transaction ,txn)))))))
+ (unless (and (eq ,result ,txn) (not ,success))
+ (return ,result))))
+ finally (error "Too many retries"))))
+|#
--- /project/elephant/cvsroot/elephant/src/db-bdb/berkeley-db.lisp 2007/01/31 22:24:16 1.6
+++ /project/elephant/cvsroot/elephant/src/db-bdb/berkeley-db.lisp 2007/02/02 23:51:58 1.7
@@ -72,6 +72,9 @@
)
+(defmacro txn-default (dvar)
+ `(if ,dvar ,dvar +NULL-VOID+))
+
;;
;; Constants and Flags
;; eventually write a macro which generates a custom flag function.
@@ -132,6 +135,8 @@
(defconstant DB_FIRST 7)
(defconstant DB_GET_BOTH 8)
(defconstant DB_GET_BOTH_RANGE 10)
+(defconstant DB_KEYFIRST 13)
+(defconstant DB_KEYLAST 14)
(defconstant DB_LAST 15)
(defconstant DB_NEXT 16)
(defconstant DB_NEXT_DUP 17)
@@ -220,8 +225,6 @@
;; makes flags into keywords
;; makes keyword args, cstring wrappers
-(defvar *errno-buffer* (allocate-foreign-object :int 1))
-
(eval-when (:compile-toplevel)
(defun make-wrapper-args (args flags keys)
(if (or flags keys)
@@ -404,7 +407,7 @@
:returning :int)
(wrap-errno db-env-open (dbenvp home flags mode)
- :flags (init-cdb init-lock init-log
+ :flags (auto-commit init-cdb init-lock init-log
init-mpool init-rep init-txn
recover recover-fatal create
lockdown private system-mem thread
@@ -423,7 +426,7 @@
(wrap-errno db-env-dbremove (env transaction file database flags)
:flags (auto-commit)
- :keys ((transaction *current-transaction*)
+ :keys ((transaction (txn-default *current-transaction*))
(database +NULL-CHAR+))
:cstrings (file database)
:transaction transaction
@@ -440,7 +443,7 @@
(wrap-errno db-env-dbrename (env transaction file database newname flags)
:flags (auto-commit)
- :keys ((transaction *current-transaction*)
+ :keys ((transaction (txn-default *current-transaction*))
(database +NULL-CHAR+))
:cstrings (file database newname)
:transaction transaction
@@ -535,7 +538,7 @@
:flags (auto-commit create dirty-read read-uncommitted
excl nommap rdonly thread truncate
)
- :keys ((transaction *current-transaction*)
+ :keys ((transaction (txn-default *current-transaction*))
(file +NULL-CHAR+)
(database +NULL-CHAR+)
(type DB-UNKNOWN)
@@ -584,7 +587,8 @@
:returning :int)
(wrap-errno db-truncate (db transaction flags) :flags (auto-commit)
- :keys ((transaction *current-transaction*)) :outs 2
+ :keys ((transaction (txn-default *current-transaction*)))
+ :outs 2
:transaction transaction
:documentation "Truncate (erase) a DB.")
@@ -625,8 +629,8 @@
:returning :int)
(defun db-get-key-buffered (db key-buffer-stream value-buffer-stream
- &key (transaction *current-transaction*)
- auto-commit get-both degree-2 read-committed
+ &key (transaction (txn-default *current-transaction*))
+ get-both degree-2 read-committed
dirty-read read-uncommitted)
"Get a key / value pair from a DB. The key is encoded in
a buffer-stream. Space for the value is passed in as a
@@ -634,7 +638,7 @@
decoding, or NIL if nothing was found."
(declare (type pointer-void db transaction)
(type buffer-stream key-buffer-stream value-buffer-stream)
- (type boolean auto-commit get-both degree-2 read-committed dirty-read read-uncommitted))
+ (type boolean get-both degree-2 read-committed dirty-read read-uncommitted))
(loop
for value-length fixnum = (buffer-stream-length value-buffer-stream)
do
@@ -644,8 +648,7 @@
(buffer-stream-size key-buffer-stream)
(buffer-stream-buffer value-buffer-stream)
value-length
- (flags :auto-commit auto-commit
- :get-both get-both
+ (flags :get-both get-both
:degree-2 (or degree-2 read-committed)
:dirty-read (or dirty-read read-uncommitted)))
(declare (type fixnum result-size errno))
@@ -675,8 +678,8 @@
(defun db-get-buffered (db key value-buffer-stream &key
(key-size (length key))
- (transaction *current-transaction*)
- auto-commit get-both degree-2 read-committed
+ (transaction (txn-default *current-transaction*))
+ get-both degree-2 read-committed
dirty-read read-uncommitted)
"Get a key / value pair from a DB. The key is passed as a
string. Space for the value is passed in as a
@@ -686,7 +689,7 @@
(type string key)
(type buffer-stream value-buffer-stream)
(type fixnum key-size)
- (type boolean auto-commit get-both degree-2 read-committed
+ (type boolean get-both degree-2 read-committed
dirty-read read-uncommitted))
(with-cstring (k key)
(loop
@@ -696,8 +699,7 @@
(%db-get-buffered db transaction k key-size
(buffer-stream-buffer value-buffer-stream)
value-length
- (flags :auto-commit auto-commit
- :get-both get-both
+ (flags :get-both get-both
:degree-2 (or degree-2 read-committed)
:dirty-read (or dirty-read read-uncommitted)))
(declare (type fixnum result-size errno))
@@ -715,8 +717,8 @@
(t (error 'db-error :errno errno)))))))
(defun db-get (db key &key (key-size (length key))
- (transaction *current-transaction*)
- auto-commit get-both degree-2 read-committed
+ (transaction (txn-default *current-transaction*))
+ get-both degree-2 read-committed
dirty-read read-uncommitted)
"Get a key / value pair from a DB. The key is passed as a
string, and the value is returned as a string. If nothing
@@ -724,7 +726,7 @@
(declare (type pointer-void db transaction)
(type string key)
(type fixnum key-size)
- (type boolean auto-commit get-both degree-2 read-committed
+ (type boolean get-both degree-2 read-committed
dirty-read read-uncommitted))
(with-cstring (k key)
(with-buffer-streams (value-buffer-stream)
@@ -735,8 +737,7 @@
(%db-get-buffered db transaction k key-size
(buffer-stream-buffer value-buffer-stream)
value-length
- (flags :auto-commit auto-commit
- :get-both get-both
+ (flags :get-both get-both
:degree-2 (or degree-2 read-committed)
:dirty-read (or dirty-read read-uncommitted)))
(declare (type fixnum result-size errno))
@@ -766,21 +767,21 @@
:returning :int)
(defun db-put-buffered (db key-buffer-stream value-buffer-stream
- &key (transaction *current-transaction*) auto-commit
+ &key (transaction (txn-default *current-transaction*))
exists-error-p)
"Put a key / value pair into a DB. The pair are encoded
in buffer-streams. T on success, or nil if the key already
exists and EXISTS-ERROR-P is NIL."
(declare (type pointer-void db transaction)
(type buffer-stream key-buffer-stream value-buffer-stream)
- (type boolean auto-commit exists-error-p))
+ (type boolean exists-error-p))
(let ((errno
(%db-put-buffered db transaction
(buffer-stream-buffer key-buffer-stream)
(buffer-stream-size key-buffer-stream)
(buffer-stream-buffer value-buffer-stream)
(buffer-stream-size value-buffer-stream)
- (flags :auto-commit auto-commit))))
+ 0)))
(declare (type fixnum errno))
(cond ((= errno 0) t)
((and (= errno DB_KEYEXIST) (not exists-error-p))
@@ -800,15 +801,14 @@
:returning :int)
(wrap-errno db-put (db transaction key key-size value value-size flags)
- :flags (auto-commit)
+ :flags ()
:keys ((key-size (length key))
(value-size (length value))
- (transaction *current-transaction*))
+ (transaction (txn-default *current-transaction*)))
:cstrings (key value)
:declarations (declare (type pointer-void db transaction)
(type string key value)
- (type fixnum key-size value-size)
- (type boolean auto-commit))
+ (type fixnum key-size value-size))
:transaction transaction
:documentation
"Put a key / value pair into a DB. The pair are strings.")
@@ -821,18 +821,17 @@
(flags :unsigned-int))
:returning :int)
-(defun db-delete-buffered (db key-buffer-stream &key auto-commit
- (transaction *current-transaction*))
+(defun db-delete-buffered (db key-buffer-stream
+ &key (transaction (txn-default *current-transaction*)))
"Delete a key / value pair from a DB. The key is encoded
in a buffer-stream. T on success, NIL if the key wasn't
found."
(declare (type pointer-void db transaction)
- (type buffer-stream key-buffer-stream)
- (type boolean auto-commit))
+ (type buffer-stream key-buffer-stream))
(let ((errno (%db-delete-buffered db transaction
(buffer-stream-buffer key-buffer-stream)
(buffer-stream-size key-buffer-stream)
- (flags :auto-commit auto-commit))))
+ 0)))
(declare (type fixnum errno))
(cond ((= errno 0) t)
((or (= errno DB_NOTFOUND)
@@ -851,16 +850,16 @@
(flags :unsigned-int))
:returning :int)
-(defun db-delete (db key &key auto-commit (key-size (length key))
- (transaction *current-transaction*))
+(defun db-delete (db key &key (key-size (length key))
+ (transaction (txn-default *current-transaction*)))
"Delete a key / value pair from a DB. The key is a
string. T on success, NIL if the key wasn't found."
(declare (type pointer-void db transaction) (type string key)
- (type fixnum key-size) (type boolean auto-commit))
+ (type fixnum key-size))
(with-cstrings ((key key))
(let ((errno
(%db-delete db transaction key
- key-size (flags :auto-commit auto-commit))))
+ key-size 0)))
(declare (type fixnum errno))
(cond ((= errno 0) t)
((or (= errno DB_NOTFOUND)
@@ -881,7 +880,7 @@
:returning :int)
(defun db-delete-kv-buffered (db key-buffer-stream value-buffer-stream
- &key (transaction *current-transaction*))
+ &key (transaction (txn-default *current-transaction*)))
"Delete a specific key / value pair from a DB with
duplicates. The key and value are encoded as
buffer-streams. T on success, NIL if the key / value pair
@@ -918,7 +917,7 @@
(end-size :unsigned-int :out))
:returning :int)
-(defun db-compact (db start stop end &key (transaction *current-transaction*)
+(defun db-compact (db start stop end &key (transaction (txn-default *current-transaction*))
freelist-only free-space)
(declare (type pointer-void db transaction)
(type buffer-stream start stop)
@@ -956,20 +955,22 @@
(errnop (* :int)))
:returning :pointer-void)
-(defun db-cursor (db &key (transaction *current-transaction*)
+(defun db-cursor (db &key (transaction (txn-default *current-transaction*))
degree-2 read-committed dirty-read read-uncommitted)
"Create a cursor."
(declare (type pointer-void db)
- (type boolean degree-2 read-committed dirty-read read-uncommitted)
- (type pointer-int *errno-buffer*))
- (let* ((curs (%db-cursor db transaction (flags :degree-2 (or degree-2 read-committed)
- :dirty-read (or dirty-read read-uncommitted))
- *errno-buffer*))
- (errno (deref-array *errno-buffer* '(:array :int) 0)))
- (declare (type pointer-void curs)
- (type fixnum errno))
- (if (= errno 0) curs
- (error 'db-error :errno errno))))
+ (type boolean degree-2 read-committed dirty-read read-uncommitted))
+ (let ((errno-buffer (allocate-foreign-object :int 1)))
+ (declare (type pointer-int errno-buffer))
+ (let* ((curs (%db-cursor db transaction
+ (flags :degree-2 (or degree-2 read-committed)
+ :dirty-read (or dirty-read read-uncommitted))
+ errno-buffer))
+ (errno (deref-array errno-buffer '(:array :int) 0)))
+ (declare (type pointer-void curs)
+ (type fixnum errno))
+ (if (= errno 0) curs
+ (error 'db-error :errno errno)))))
(def-function ("db_cursor_close" %db-cursor-close)
((cursor :pointer-void))
@@ -1005,13 +1006,15 @@
(defun db-cursor-duplicate (cursor &key (position t))
"Duplicate a cursor."
(declare (type pointer-void cursor))
- (let* ((newc (%db-cursor-dup cursor (flags :position position)
- *errno-buffer*))
- (errno (deref-array *errno-buffer* '(:array :int) 0)))
- (declare (type pointer-void newc)
- (type fixnum errno))
- (if (= errno 0) newc
- (error 'db-error :errno errno))))
+ (let ((errno-buffer (allocate-foreign-object :int 1)))
+ (declare (type pointer-int errno-buffer))
+ (let* ((newc (%db-cursor-dup cursor (flags :position position)
+ errno-buffer))
+ (errno (deref-array errno-buffer '(:array :int) 0)))
+ (declare (type pointer-void newc)
+ (type fixnum errno))
+ (if (= errno 0) newc
+ (error 'db-error :errno errno)))))
(def-function ("db_cursor_get_raw" %db-cursor-get-key-buffered)
((cursor :pointer-void)
@@ -1377,35 +1380,35 @@
(errno (* :int)))
:returning :pointer-void)
-(defun db-transaction-begin (env &key (parent *current-transaction*)
+(defun db-transaction-begin (env &key parent
degree-2 read-committed dirty-read read-uncommitted
txn-nosync txn-nowait txn-sync)
"Start a transaction. Transactions may be nested."
(declare (type pointer-void env parent)
(type boolean degree-2 read-committed dirty-read read-uncommitted
- txn-nosync txn-nowait txn-sync)
- (type pointer-int *errno-buffer*))
- (let* ((txn
- (%db-txn-begin env parent
- (flags :degree-2 (or degree-2 read-committed)
- :dirty-read (or dirty-read read-uncommitted)
- :txn-nosync txn-nosync
- :txn-nowait txn-nowait
- :txn-sync txn-sync)
- *errno-buffer*))
- (errno (deref-array *errno-buffer* '(:array :int) 0)))
- (declare (type pointer-void txn)
- (type fixnum errno))
- (if (= errno 0)
- txn
- (error 'db-error :errno errno))))
+ txn-nosync txn-nowait txn-sync))
+ (let ((errno-buffer (allocate-foreign-object :int 1)))
+ (declare (type pointer-int errno-buffer))
+ (let* ((txn
+ (%db-txn-begin env parent
+ (flags :degree-2 (or degree-2 read-committed)
+ :dirty-read (or dirty-read read-uncommitted)
+ :txn-nosync txn-nosync
+ :txn-nowait txn-nowait
+ :txn-sync txn-sync)
+ errno-buffer))
+ (errno (deref-array errno-buffer '(:array :int) 0)))
+ (declare (type pointer-void txn)
+ (type fixnum errno))
+ (if (= errno 0)
+ txn
+ (error 'db-error :errno errno)))))
(def-function ("db_txn_abort" %db-txn-abort)
((txn :pointer-void))
:returning :int)
(wrap-errno (db-transaction-abort %db-txn-abort) (transaction)
- :keys ((transaction *current-transaction*))
:declarations (declare (type pointer-void transaction))
:documentation "Abort a transaction.")
@@ -1415,106 +1418,18 @@
:returning :int)
(wrap-errno (db-transaction-commit %db-txn-commit) (transaction flags)
- :keys ((transaction *current-transaction*))
:flags (txn-nosync txn-sync)
:declarations (declare (type pointer-void transaction)
(type boolean txn-nosync txn-sync))
:documentation "Commit a transaction.")
-#|
-(defmacro with-transaction ((&key transaction environment
- (parent '*current-transaction*)
- (retries 100)
- dirty-read read-uncommitted
- txn-nosync txn-nowait txn-sync)
- &body body)
[208 lines skipped]