About performance
Your concern is legit, but I think you should start addressing the issue from a different angle first. Focus first on the connection pool size. Regarding Java's connection pool, it may interest you HikariCP. Once you are confident about the reliability and size of the connection pool. Perform load tests.
Simulate those +1K concurrent votes and track errors that might cause you to miss votes. If you have a way to assert the total count vs the expected one, make sure the assertion is checked in the end.
Once you have a complete report with successful and failed requests, locate (by error codes and logs) what caused the errors. Or what caused the large number of them1.
Did you run out of connections? Make it larger. Did connections run out of time? Look for transaction locks, or set larger timeouts. Did you run out of memory? Look for memory leaks. Did you find none? Give a bit more room to the Heap. Make step increments tho (%5, 10%, 15%, etc.). Did you find vote computing getting slow over time? Try computing votes in parallel.
In other words, spot performance issues and tune up first with what you have. Find a good balance between resources and performance. Then scale or improve the design.
About design
Can you afford missing votes?
If not, then don't cache/buffer any. Make atomic transactions so that if one fails, the client is reported immediately and inform the user his vote doesn't count.
If yes, then it might interest you the write-through cache pattern.
I have implemented this pattern once to track users' last activity date and time. I used those values to check when an account became officially inactive and eligible for oblivion.
Every time I tracked user activity, I updated the cache with the date and time of the account causing the activity.
The flush strategy was as simple as
- After 1000 hits (to prevent the cache from growing too much)
- A cron job checking the cache every few minutes to prevent the cache from getting too old due to low activity or 0 activity. Also to prevent memory leaks.
The flush resulted in several transactions, all using the same DB connections, so not a problem at all. Maybe, you could solve the flush with a couple of transactions (upvotes and downvotes) or in a single one if only the overall result matters.
1: Load tests usually show behavioural patterns of the system under stress. Look for them