It's possible, and in fact it's dead simple, as long as you're okay with where mark already is. There's no pre-existing command for it, but you could use this:
(defun my/activate-region-only ()
"Activate the region without changing the mark ring."
(setq mark-active t))
If you want to set the mark without adding it to the mark ring, you start running into problems. The naive implementation would be something like this:
(defun my/set-mark-no-push ()
"Set mark at point; activate region. Do not change mark ring."
But this probably won't behave as you expect. It won't change the mark ring, but the current mark isn't on the mark ring. It only gets sent to the mark ring when a new mark gets set. Most commands that interact with the mark ring (e.g.,
C-u C-SPC) behave as if the current mark were on top of the mark ring, but this is sort of an illusion.
The upshot of all this is that
my/set-mark-no-push, above, will prevent the previous mark from getting put onto the mark ring, but the new mark will still get into the mark ring when some subsequent command sets the mark again. If you want to set the mark without letting the new value go to the mark ring, there doesn't seem to be a clean or easy way to do it, and you're probably better off learning to live with Emacs's eccentricity in this respect.
EDIT: Okay, this turned out to be easier than I thought. Here's what I've got:
(defun my/dont-push-mark (&optional location nomsg activate)
"As `push-mark', but don't push old mark to mark ring."
(setq location (or location (point)))
(if (or activate (not transient-mark-mode))
(set-marker (mark-marker) location))
(or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
(message "Mark set"))
(advice-add #'push-mark :override #'my/dont-push-mark)
Most of the code here dealing with NOMSG and ACTIVATE I lifted directly from
push-mark. Three caveats:
This will only modify the behavior of functions that use
push-mark. That should be most of them, but there may be functions that, for whatever reason, use some other method to add a mark to the mark ring.
Naturally, functions that are expecting to change the mark ring may behave unpredictably with this in effect.
Most importantly, this change will be global. If you want to use the mark ring at all, you may want to write an interface that will add and remove the advice temporarily.