When you use ZooKeeper for leader election you can't guarantee uniqueness of the leader.It's possible to run into this situation even without GC pauses. For example, when a leader is isolated from the ZooKeeper quorum during a network partitioning or when a leader issues a long running query, dies and a new leader can issue a new query while the current is still active.
The workaround is to use compare-and-set when you update the database. Once new leader is elected you should get an increasing leader id (e.g. by updating a node in ZooKeeper and using its version or mzxid) and use it to guard each transaction issued by that leader.
For example if you want to change the state of the db then instead of the following transaction:
BEGIN TRANSACTION;
db.update($change);
END TRANSACTION;
you should use something like
BEGIN TRANSACTION;
if (db.leaderID <= $leaderID) {
db.leaderID = $leaderID;
db.update($change);
}
END TRANSACTION;
This trick will protect your system from uncertainties caused by concurrent leaders. Of course your database should be linearizable and support compare-and-set.