It is highly recommended NOT to use the `uvm_do_* macros. The macros remove some of the control that the user might want such as object handle reuse, constraint manipulation and direct variable assignment. The user should just use the standard methods for creating, randomizing and sending sequence items.
The answer to your question comes from the SystemVerilog LRM. If you don't have a copy, it is available for free.
18.7 In-line constraints — randomize() with
By using the randomize() with construct, users can declare in-line constraints at the point where the randomize() method is called. These additional constraints are applied along with the object constraints.