CRM-17629, Tim Otten:
4. I'm aware of one anomaly in this area, but it's not in "Mailer Batch Limit". The issue is that we have several locks involved in a CiviMail delivery (e.g. one set of locks for #cron-workers; another set of locks for the CiviMail job ID#s; and another set of locks for updating caches). However, the underlying lock mechanism (MySQL's GET_LOCK) only allows a thread to hold one lock at a time. The class CRM_Core_Lock has some very evil hacks which basically disregard certain locks when processing CiviMail. (IIRC, the lock for job ID# takes precedence, and all other locks become irrelevant in its presence, but it's hard to tell from skimming the code.)
5. To fix the locking problem, we basically need either:
(a) Require MySQL 5.7+ (which fixes GET_LOCK()). Then remove the various hacks.
(b) Write a new implementation of Civi\Core\LockInterface without GET_LOCK - instead, use files, SQL tables/rows, memcache/redis, or maybe some dedicated lock service. (To enable the new implementation, see Civi\Core\Container::createLockManager.)