I'm currently working in a legacy application that uses an Stored Procedure in a Sybase DB to generate some IDs incrementally. The procedure is defined as:
CREATE PROC getId
(@val int = -1 output)
AS
BEGIN
UPDATE ID_TABLE SET LAST_VALUE = LAST_VALUE + 1
SELECT @val = LAST_VALUE FROM ID_TABLE
RETURN @val
END
This procedure is being called from a Java application using Spring's TransactionTemplate
to handle the transaction in a declarative manner.
public Integer getId() {
TransactionTemplate txTemplate = new TransactionTemplate(txManager); // txManager is an autowired instance of PlatformTransactionManager.
txTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
txTemplate.setTimeout(-1);
return (Integer) txTemplate.execute((TransactionCallback) status -> idDao.generateId());
}
Internally, idDao uses a JdbcTemplate
to call the Stored Procedure using a CallableStatementCreatorFactory
. Nothing too out of the ordinary there.
The Stored Procedure is called ~10k times/day. From time to time, we see some ID collisions. My understanding was that the isolation level being set to SERIALIZABLE should prevent this from happening, and I can't seem to reproduce this even calling getId
simultaneously with several threads. Does anybody have a hint on what might be happening here?