I think you are mixing handler-case with handler-bind.  With
handler-case, control is transferred to the handler-case's
error-clause by unwinding the dynamic state.  With handler-bind, this
unwinding does not occur.
  Here are rewrites for your examples which do what, I believe, you
were trying to achieve:
(defun handle ()
   (handler-bind ((error #'(lambda (&rest x) (invoke-restart 'hi))))
     (raise)))
;; same as your message
(defun raise ()
   (restart-case (error "raise")
     (hi () (princ "HI THERE"))))
 = = = 
;; same as your message
(defvar *xx* 'global)
(defun a ()
   (handler-bind ((condition #'(lambda (&rest x) (print *xx*))))
     (b)))
;; same as your message
(defun b ()
   (let ((*xx* 'local))
      (error "b")))
	Charley
---
Charles A. Cox, Franz Inc.        1995 University Avenue, Suite 275
Internet: <franz.com at cox>           Berkeley, CA  94704
WWW: http://www.franz.com/        Phone: (510) 548-3600; FAX: (510) 548-8253