This is because the line readonly V="$(cat non-existant-file)" is not a simple assignment: it is the composition of an assignment that fails, followed by the instruction readonly V, which succeeds.
That explains the behavior you observed, and this Bash pitfall is mentioned for a similar construct (local) in the documentation BashFAQ/105 indicated by @codeforester.
So, if you try instead the following code, you should observe the behavior you expect:
#!/bin/bash
set -ex
V=$(cat non-existant-file)
readonly V
echo "var V: $V"
Minor remarks:
I corrected the shebang that should be #!/usr/bin/env bash or #!/bin/bash, not !#/bin/bash
I replaced V="$(cat non-existant-file)" with V=$(cat non-existant-file) because the quotes are unnecessary here.