Have you looked into STAR?
I don't know if anybody truly tested performance with short reads, but it has worked well for me in the past with <50nt reads.
I had to change a number of options, gleaned from https://github.com/alexdobin/STAR/issues/169, since I also wanted to retain soft-clipping.
--outFilterScoreMinOverLread 0 --outFilterMatchNminOverLread 0 --outFilterMatchNmin 0 --outFilterMismatchNmax 2
From my understanding, setting the the first two to 0 (the third one should be same as default value) helps with soft-clipping of short reads. In theory, at its default value of 0.66, with a 45nt read, you may be able to clip up to 15 bp, but I haven't seen if this performs as expected, and I'm sure the interplay of Scoring/number of matches complicates the picture a little bit.
For a little more context, when left these at their default (0.66) or changed to (0.3) the majority of reads were "too short" unmapped reads. After setting the above options, the rate was rescued and mapping seemed to behave as expected, but I didn't check extensively for any mistakes.
So, if you set those first to options to 0, you should be able to explicitly control mismatches using the last option and still retain soft clipping.
Unless you need gapped alignments (which you probably don't need with reads < 45 bp) using
bowtie v.1.xmay be a better choice.You are right, bowtie 1 has -v which let's me set a maximum number of mismatches, but I lose the reads that used to align thanks to soft clipping. I may have to run both if no other answer comes up. According to bowtie2 docs, I should be able to replace the -v command by changing my scoring options, but that's why I posted my question initially.