protected void writeOneBatch() throws InterruptedException {
        // waiting if necessary until an element becomes available
        currentJournal = journalQueue.take();
        long nextJournalId = nextVisibleJournalId;
        initBatch();

        try {
            this.journal.batchWriteBegin();

            while (true) {
                journal.batchWriteAppend(nextJournalId, currentJournal.getBuffer());
                currentBatchTasks.add(currentJournal);
                nextJournalId += 1;

                if (shouldCommitNow()) {
                    break;
                }

                currentJournal = journalQueue.take();
            }
        } catch (JournalException e) {
            // abort current task
            LOG.warn("failed to write batch, will abort current journal {} and commit", currentJournal, e);
            abortJournalTask(currentJournal, e.getMessage());
        } finally {
            try {
                // commit
                journal.batchWriteCommit();
                LOG.debug("batch write commit success, from {} - {}", nextVisibleJournalId, nextJournalId);
                nextVisibleJournalId = nextJournalId;
                markCurrentBatchSucceed();
            } catch (JournalException e) {
                // abort
                LOG.warn("failed to commit batch, will abort current {} journals.",
                        currentBatchTasks.size(), e);
                try {
                    journal.batchWriteAbort();
                } catch (JournalException e2) {
                    LOG.warn("failed to abort batch, will ignore and continue.", e);
                }
                abortCurrentBatch(e.getMessage());
            }
        }

        rollJournalAfterBatch();

        updateBatchMetrics();
    }
@Ignore
    @Test
    public void testBatchWriteCommitAbortException() throws Exception {
        JournalTask task1 = new JournalTask(System.nanoTime(), makeBuffer(10), -1);
        journalQueue.add(task1);

        new Expectations(journal) {
            {
                journal.batchWriteBegin();
                times = 2;

                journal.batchWriteAppend(anyLong, (DataOutputBuffer) any);
                times = 3;

                journal.batchWriteAbort();
                times = 2;
                result = null; // success first time
                result = new JournalException("mock batchWriteAbort exception");

                journal.batchWriteCommit();
                times = 2;
                result = new JournalException("mock batchWriteCommit exception");  // task1
                result = new JournalException("mock batchWriteCommit exception");  // task1 & task2
            }
        };

        // commit failed but abort succeed
        Assert.assertEquals(1, abortedWriter.nextVisibleJournalId);
        abortedWriter.writeOneBatch();
        Assert.assertEquals(1, abortedWriter.nextVisibleJournalId);
        Assert.assertFalse(task1.get());
        Assert.assertEquals(0, journalQueue.size());

        // both commit & abort failed
        JournalTask task2 = new JournalTask(System.nanoTime(), makeBuffer(11), -1);
        journalQueue.add(task1);
        journalQueue.add(task2);
        abortedWriter.writeOneBatch();
        Assert.assertEquals(1, abortedWriter.nextVisibleJournalId);
        Assert.assertFalse(task1.get());
        Assert.assertFalse(task2.get());
        Assert.assertEquals(0, journalQueue.size());
    }