While working with a client running HPCM 188.8.131.52.110, we were encountering intermittent errors while executing rules:
“javax.persistence.RollbackException: Transaction rolled back because transaction was set to RollbackOnly”
As the exact same rule could be re-run without any errors, it appeared to be application/environment related. (also appeared to be database related given the content of the error)
Reviewing the profitability log provides a much clearer view of the issue
NOTE: Log would typically be found in a location similar to: \Oracle\Middleware\user_projects\domains\EPMSystem\servers\Profitability\logs\hpcm.log
From the log file snippet above, note the highlighted section:
“[SQL Server] Arithmetic overflow error converting expression to data type smallinit.”
What is the Problem?
While this does not match the error message we see in the user interface, this is definitely related as:
- The error message was logged at the same time as the error in HPCM
- The user name logged corresponded to the user receiving the error
- SQL Server rolling back a transaction after a failed insert makes a lot of sense.
(very) Loosely speaking, database transactions exist to protect the integrity of a database. If a program, or user, were to execute a series of statements against a database and one or more fail, what should happen? Should we leave the database in an inconsistent state or should we put the database back and alert the user? While application developers could build this logic into their program code, it is a lot more convenient to give the database a series of steps and let it handle that for us!
In this case, the INSERT statement is part of a transaction. Since the INSERT failed, SQL Server has rolled back the entire transaction and reported that to HPCM.
Why are we encountering this problem?
While that explain what happened, why did this happen? The error in the log file has four key clues :
- We are attempting to add data to a database table (INSERT INTO)
- The table is: HPM_STAT_DETAIL
- ARITHMETIC OVERFLOW occurred when trying to store a value in a column
- The target column has a Data Type of smallint
In SQL Server, a smallint datatype can have a maximum value of 32,767. Another look at the error message reveals one numeric, 43,014, which exceeds 32,767. This value is being stored in a column called JAVA_THREAD. As JAVA_THREAD is storing the process id, which is semi-randomly generated, if the number returned is < 32,768, the program works as expected. If the ID is > 32,767, then things don’t go as well…..
Reviewing the table structure for this table confirms the suspicion.
How to fix this
The easiest fix for this issue is to change the datatype for this column from smallint to int. As the largest int value is well over 2 Billion, this issue should not occur again.
LEGALESE – While I have reviewed this change with Oracle and am very confident this will not cause any issues, proceed at your own risk. 🙂
- As of 6/26, Oracle has confirmed this as a BUG. No ETA on an update yet, though.
- This may be SQL Server specific, have not evaluated against Oracle schema to confirm data type used. [Oracle equivalent of smallint would be number(1)]