Ignore:
Timestamp:
08/19/09 21:03:09 (11 years ago)
Author:
sjamaan
Message:

Implement transaction support (including nested transactions)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • release/4/postgresql/trunk/postgresql.scm

    r14796 r15517  
    2727  connect reset-connection disconnect connection?
    2828 
    29   multi-query query query*
     29  multi-query query query* with-transaction in-transaction?
    3030 
    3131  result? clear-result! row-count column-count
     
    218218;;;;;;;;;;;;;;;;;;;;
    219219
    220 (define-record pg-connection ptr type-parsers oid-parsers type-unparsers)
     220(define-record
     221  pg-connection ptr
     222  type-parsers oid-parsers type-unparsers
     223  transaction-depth)
    221224(define connection? pg-connection?)
    222225
     
    275278     (else
    276279      (let ((conn (make-pg-connection conn-ptr type-parsers
    277                                       (make-hash-table) type-unparsers)))
     280                                      (make-hash-table) type-unparsers 0)))
    278281        ;; We don't want libpq to piss in our stderr stream
    279282        ((foreign-lambda* void ((pgconn* conn))
     
    621624                         conn query params format))))
    622625
     626;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     627;;;; Transaction management
     628;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     629
     630(define (with-transaction conn thunk)
     631  (let* ((old-depth (pg-connection-transaction-depth conn))
     632         (rollback!
     633          (lambda ()
     634            (if (= old-depth 0)
     635                (query conn "ROLLBACK")
     636                ;; We do not *need* to give savepoints unique names,
     637                ;; but it aids debugging and we know the depth anyway.
     638                (query conn (conc "ROLLBACK TO SAVEPOINT s_" old-depth)))))
     639         (commit!
     640          (lambda ()
     641            (if (= old-depth 0)
     642                (query conn "COMMIT")
     643                (query conn (conc "RELEASE SAVEPOINT s_" old-depth))))))
     644    (if (= old-depth 0)
     645        (query conn "BEGIN")
     646        (query conn (conc "SAVEPOINT s_" old-depth)))
     647    (pg-connection-transaction-depth-set! conn (add1 old-depth))
     648    ;; TODO: Add a warning mechanism (using dynamic-wind) for when the
     649    ;; user tries to jump into/out of transactions with continuations?
     650    (handle-exceptions exn
     651      (begin
     652        (pg-connection-transaction-depth-set! conn old-depth)
     653        (rollback!)
     654        (raise exn))
     655      (let ((res (thunk)))
     656        (pg-connection-transaction-depth-set! conn old-depth)
     657        (if res (commit!) (rollback!))
     658        res))))
     659
     660(define (in-transaction? conn)
     661  (> (pg-connection-transaction-depth conn) 0))
     662
    623663;;;;;;;;;;;;;;;;;;;;;;
    624664;;;; Value escaping
Note: See TracChangeset for help on using the changeset viewer.