You can first use the
show_transfers command in
monero-wallet-cli to see if your transaction shows there. It should show as "pending". Subsequently, you can use the
flush_txpool command in
monerod (the daemon). The wallet will shortly notice this and change the status of the transaction from "pending" to "failed". In order to get the right balance, however, you also need to run the
rescan_spent command in
monero-wallet-cli. Note that this minor bug (i.e. not showing the correct balance) is fixed in master currently, but not yet present in the binaries (which you are likely using).
If this doesn't work, you will have to use the
rescan_bc command in
Also, what steps can I take to prevent a transaction from getting stuck as pending in the future?
Make sure your daemon is fully synced before sending out a transaction.
EDIT 11/9/2017: Currently, transactions will drop from the local mempool after 24 hours, which will result in the transaction status changing to
monero-wallet-cli. Therefore, this answer is not applicable anymore. If, however, your transaction is not relayed and your transaction is time sensitive, you can still apply this answer. You can check if your transaction is relayed by checking the mempool on block explorers like, for instance, XMRchain, MoneroBase, or MoneroBlocks.