org.springframework.dao.CannotAcquireLockException for select sql query - java

I am getting org.springframework.dao.CannotAcquireLockException for select statment. Not sure why spring is trying to put lock for select query.
I am using NamedParameterJdbcTemplate and performing queryforlist. Its all select statements so we are not using and transactions. This database is shared so it might possible there are other application who are writing or performed lock but my app is just read.
This is MS SQL Server.
I am getting exception after 3 secs so looks like spring is trying to get lock and waited for 3 sec and then throws exception.
Below is full exception.
org.springframework.dao.CannotAcquireLockException: PreparedStatementCallback; SQL [select id ticketDBId from fpscdb002_ws_004.incident where ticket_number = ?]; Lock request time out period exceeded.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Lock request time out period exceeded.
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:259)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:695)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:772)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:211)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForMap(NamedParameterJdbcTemplate.java:238)
at com.abc.servicedesk.fp.dao.FPBaseDAO.getTicketDbId(FPBaseDAO.java:44)

Related

SQL Server query throws Deadlock Exception on rs.next

We run a SELECT statement using preparedStatement.executeQuery on a SQL Server database. The query fails with a deadlock exception which is expected. The problem here is, the exception is not thrown on the executeQuery but thrown while we are doing rs.next() ie., while reading the result set. Is there any reason for this behaviour? What can we do to make it throw the exception on executeQuery?
Driver jar - sqljdbc4 - 4.0.2206.100
Java version - 1.8
Query Executed: SELECT Col1 from Table1 where Col2 = ?
Error trace:
com.microsoft.sqlserver.jdbc.SQLServerException: Transaction (Process ID 66) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:217)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:6357)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1798)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:1049)

Record inserted but still not found

I was currently using java spring jdbctemplate to insert and select record. However, Now the system have go for production, some issue has happen. This system will prevent record duplicate by select the record by certain key to check is it already exist. However, I notice the 1st transaction after inserted into database, then the 2nd transaction come in, jdbc template select still show that record was not found? I notice this will happen if the 2 transaction was submitted within a milliseconds different...
The record time was
e.g.
1st Record insert - 15/6/17 12:22:39,986 - insert success
2nd record select - 15/6/17 12:22:44,680 - search record show not found?
Sample insert log
15/6/17 12:22:39,937 DEBUG [30:http-nio-8080-exec-2] (org.springframework.jdbc.core.JdbcTemplate:869) Executing prepared SQL update
15/6/17 12:22:39,938 DEBUG [30:http-nio-8080-exec-2] (org.springframework.jdbc.core.JdbcTemplate:616) Executing prepared SQL statement [INSERT INTO ...;]
15/6/17 12:22:39,950 DEBUG [30:http-nio-8080-exec-2] (org.springframework.jdbc.core.JdbcTemplate:879) SQL update affected 1 rows
15/6/17 12:22:39,951 DEBUG [30:http-nio-8080-exec-2] (org.springframework.jdbc.core.JdbcTemplate:869) Executing prepared SQL update
15/6/17 12:22:39,952 DEBUG [30:http-nio-8080-exec-2] (org.springframework.jdbc.core.JdbcTemplate:616) Executing prepared SQL statement [INSERT INTO ...;]
15/6/17 12:22:39,965 DEBUG [30:http-nio-8080-exec-2] (org.springframework.jdbc.core.JdbcTemplate:879) SQL update affected 1 row
15/6/17 12:22:39,970 DEBUG [30:http-nio-8080-exec-2] (org.springframework.jdbc.datasource.DataSourceUtils:327) Returning JDBC Connection to DataSource
Sample select log
15/6/17 12:22:44,680 DEBUG [29:http-nio-8080-exec-1] (org.springframework.jdbc.core.JdbcTemplate:682) Executing prepared SQL query
15/6/17 12:22:44,680 DEBUG [29:http-nio-8080-exec-1] (org.springframework.jdbc.core.JdbcTemplate:616) Executing prepared SQL statement [SELECT * FROM ...]
Please note that this system was set in 2 different server by using load balancing. They both point to the same database. The insert was completed on server 1 because it already return the connection to the jdbc connection pool. A new transaction come in the server 2, select but no record found?
I wonder why it still cannot found event after insert was finish? Is it because of the time delay?
This question had been resolved. It was due to the server time not consistent. Thanks
RealSkeptic

Spring sql-error-codes.xml does not show correct exception on timeout

The following error occurs when an exception occurs for myJDBCTemplate.queryForList() , before which a setQueryTimeout(1) is set. I have a database which has 1.2 million rows, and looking for the timeout exception to be printed or occur in the case when the statement is executed. So, basically, the timeout occurs but the exception does not mention that.
I am using springFramework-version => 4.1.3.RELEASE in pom.xml
INFO: org.springframework.beans.factory.xml.XMLBeanDefinitionReader - Loading XML bean definition for class path resource [org/springframework/jdbc/support/sql-error-code.xml]
org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [select * from myTable where userCategory='1']; SQL state [70100]; error code [1317]; Query execution was interrupted; nested exception is java.sql.SQLException: Query execution was interrupted
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:416)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:471)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:481)
……..
caused by java.sql.SQLExcepion: Query execution was interrupted.
From the answer found at Query execution was interrupted, error #1317 states, the interruption occurs because of timeout, which I think is the possible cause.
Also, the exception states it is caused by java.sql.SQLException, but there are no exact details, why it occurred? So, I am not sure is it because of timeout or something else.
The error is clear in your stack trace:-
error code [1317]; Query execution was interrupted
, which means your query is being interrupted by an execution time limit. This error occurs when your query takes an unexpectedly long time to execute.
The error can be solved by fetching the data in batches by executing the query repeatedly for a certain data range.

Resource governor for 'prepared statements' exceeded

We are using Spring JDBCTemplate 2.5 version and getting below exception when used batchupdate method.
Exception thrown!
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [SELECT SERVICE WHERE CREATE_TIME >= ? AND CREATE_TIME < ?]; SQL state [HY000]; error code [-685]; [Sybase][JDBC Driver][SQL Anywhere]Resource governor for 'prepared statements' exceeded; nested exception is java.sql.SQLException: [Sybase][JDBC Driver][SQL Anywhere]Resource governor for 'prepared statements' exceeded
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.translate(SQLStateSQLExceptionTranslator.java:124)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:322)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:607)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:641)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:670)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:678)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:710)
at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:187)
Could you please let me know if it is known issue? if so how to get it resolved.
From the documentation:
Applications that use prepared statements can receive the error "Resource governor for 'prepared statements' exceeded" if the prepared statements are not explicitly dropped once they are no longer required.
So you probably should review your code for non-closed prepared statement or adjust your sybase "max_statement_count" parameter. The later seems more likely as you are using JdbcTemplates

org.springframework.jdbc.UncategorizedSQLException:PreparedStatementCallback; nested exception is com.ibm.db2.jcc.am.SqlException:

I get a
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException.
SQL state [51002]; error code [-805]; DB2 SQL Error: SQLCODE=-805, SQLSTATE=51002, SQLERRMC=NULLID.SYSLH203 0X5359534C564C3031, DRIVER=3.65.102; nested exception is com.ibm.db2.jcc.am.SqlException: DB2 SQL Error: SQLCODE=-805, SQLSTATE=51002, SQLERRMC=NULLID.SYSLH203 0X5359534C564C3031, DRIVER=3.65.102
for the following sql:
SELECT REF_TBL_ENTY_KEY, LTRIM(RTRIM(REF_TBL_ID)) AS REF_TBL_ID, LTRIM(RTRIM(COMP_ID1)) AS COMP_ID1, LTRIM(RTRIM(LOW_VAL1)) AS LOW_VAL1, LTRIM(RTRIM(HI_VAL1)) AS HI_VAL1, LTRIM(RTRIM(COMP_ID2)) AS COMP_ID2, LTRIM(RTRIM(LOW_VAL2)) AS LOW_VAL2, LTRIM(RTRIM(HI_VAL2)) AS HI_VAL2, LTRIM(RTRIM(COMP_ID3)) AS COMP_ID3, LTRIM(RTRIM(LOW_VAL3)) AS LOW_VAL3, LTRIM(RTRIM(HI_VAL3)) AS HI_VAL3, LTRIM(RTRIM(COMP_ID4)) AS COMP_ID4, LTRIM(RTRIM(LOW_VAL4)) AS LOW_VAL4, LTRIM(RTRIM(HI_VAL4)) AS HI_VAL4, LTRIM(RTRIM(COMP_ID5)) AS COMP_ID5, LTRIM(RTRIM(LOW_VAL5)) AS LOW_VAL5, LTRIM(RTRIM(HI_VAL5)) AS HI_VAL5, LTRIM(RTRIM(COMP_ID6)) AS COMP_ID6, LTRIM(RTRIM(LOW_VAL6)) AS LOW_VAL6, LTRIM(RTRIM(HI_VAL6)) AS HI_VAL6 FROM TBL_CODE WHERE DOM_NBR = ? AND REF_TBL_ID = ? AND EFF_DT <= ? AND END_DT >= ? AND LOW_VAL1 <= 'ABX' AND HI_VAL1 >= 'ABX' ORDER BY REF_TBL_ID, LOW_VAL1, HI_VAL1, LOW_VAL2, HI_VAL2, LOW_VAL3, HI_VAL3, LOW_VAL4, HI_VAL4, LOW_VAL5, HI_VAL5, LOW_VAL6, HI_VAL6, EFF_DT
I am using this sql in jdbcTemplate queryForList and am passing the required number of parameters. This error doesn't happen at all times.
This sql is being run as part of a long running batch job processing application. The application is single threaded. The application code DOES NOT open or close any connections explicitly.
I am using commons Dbcp(version 1.4) for connection pooling and spring JDBC(version 3.2.8) for data access. I have tried running it with BasicDataSource maxActive = 50 and maxActive=8(default for BasicDataSource) and I receive error in both cases.
In researching this issue I came accross this link from IBM website - http://www-01.ibm.com/support/docview.wss?rs=71&uid=swg21208123
The previous version of the application which used an in-house connection pooling framework and managed its own data access did not throw this exception. I want to make sure that the application code is fine before I request the DBA to create more packages on the server.
Any help will be greatly appreciated.

Categories