Imagine a bank transfer of 100 dollars where the source account lives in shard A and the destination in shard B. The coordinator sends PREPARE to both shards. Shard A checks the balance, deducts 100 in its log, locks the row, and votes YES. Shard B logs the 100 credit, locks its row, and votes YES.
Both votes are in, so the coordinator writes COMMIT to its log and tells both shards to commit. Money leaves A and lands in B atomically. If instead shard A had reported insufficient funds and voted NO, the coordinator would have written ABORT, and shard B would have rolled back its prepared credit so no money appears out of nowhere.
Now suppose the coordinator crashes right after both shards voted YES but before it sent the decision. Both shards sit in the prepared state with rows locked, unable to commit or abort, until the coordinator restarts, reads its log, sees no commit record, and replays the protocol to a safe conclusion. That stuck interval is exactly the blocking behavior 2PC is famous for.