Record inserted but still not found - java

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

Related

Session.flush() causes org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 1 actual row count: 0 expected: 1

I have a java back-end web application that just started throwing an error after some sort of database update.
I've been able to isolate the code to a single line in which a Session variable is being flushed:
Session session=getSession();
session.saveOrUpdate(parm);
session.flush(); //This is where it errors
And it throws this error:
ERROR AbstractFlushingEventListener Could not synchronize database state with session
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 1 actual row count: 0 expected: 1
The code hasn't changed in over a year; it just started throwing this error.
Any suggestions?
Thanks
This error usually caused when the hibernate can't find all the rows it needs to update. Meaning that when you try to update some objects that were pulled from the DB they don't really exist anymore (or never existed in the first place).
It might be because another thread is deleting them or that the DB's isolation mode is set to read_uncommited and so rows that were created by another transaction failed to save (due to a transaction failure) and don't exist anymore.
ref: https://stackoverflow.com/questions/21625059/org-hibernate-stalestateexception-batch-update-returned-unexpected-row-count-fr

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)

org.springframework.dao.CannotAcquireLockException for select sql query

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)

Spring Jdbc template Row mapper is not setting all values in Object

I am using spring jdbc template to retreive 400 records from oracle database.
After that i am using row mapper to convert rows to objects. Some of the values in object are not having any values. when i test same sql in pl/sql editor, i am able to see all rows and all columns for rows. When i debug application, i am getting below error. If i fetch less number of records(7) for same query, it is working fine.Row mapper is setting all values for object. Can you please help me on this.
java.sql.SQLException: statement handle not executed
2017-02-09 15:45:39 INFO XmlBeanDefinitionReader:317 - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2017-02-09 15:45:39 INFO SQLErrorCodesFactory:126 - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]
2017-02-09 15:45:39 WARN SQLErrorCodesFactory:227 - Error while extracting database product name - falling back to empty error codes
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Connection has already been closed.
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:305)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:329)
at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:214)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:134)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:97)
at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:707)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:757)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:192)
If retrieving those 400 rows from the database take some time, I assume you are hitting DB connection timeout. If so, increase connectionTimeout if you are using resource pool. Timeout could happen while you are debugging the code, too.
Could also be that timeout is on the database side. In that case, you'll have to tweak DB timeout parameters.

Hibernate does not evict query cache (non repeatable read issue)

I am a new to java/spring/hibernate and really felt in love in java after several years of .Net programming.
now I am working on web app using Spring (MVC, declarative transactions) and Hibernate (3.6, as cache provier - ehCache 2.5). I've got some read only and read-write enitties that I would like to cache using Hibernate second cache and query cache.
everything was alright when I used caching for read only entities. I added read-write entity and ran performance tests using jMeter. For read-write entities I am facing with the issue of non repeatable read. E.g. there are several concurrent threads reading and writing to entity table.
Thread 3 gets lookup values:
16:34:45,304 DEBUG [http-bio-8080-exec-3] cache.StandardQueryCache: (StandardQueryCache.java:136) - cached query results were not up to date
16:34:45,304 DEBUG [http-bio-8080-exec-3] hibernate.SQL:(SQLStatementLogger.java:111) - select virtualdev0_.virtual_device_class_id as virtual1_45_, virtualdev0_.virtual_device_class as virtual2_45_, virtualdev0_.sitebox_id as sitebox3_45_, virtualdev0_.timestamp as timestamp45_ from virtual_device_class virtualdev0_ where virtualdev0_.sitebox_id=?
It finds out that cache is not up to date and loads entities, adds them to second level cache, materializes and returns… continuous process from here and up to 16:34:45,826
Meanwhile Thread 9 deletes one of entities and updates second level cache + timestamp:
16:34:45,799 DEBUG [http-bio-8080-exec-9] hibernate.SQL:(SQLStatementLogger.java:111) - delete from virtual_device_class where virtual_device_class_id=?
16:34:45,814 DEBUG [http-bio-8080-exec-9] cache.UpdateTimestampsCache:(UpdateTimestampsCache.java:95) - Invalidating space [virtual_device_class], timestamp: 5466792287494145
Thread 3 continues house keeping activities and finally adds query result to query cache (notice that timestamp will be higher than timpestamp for delete action of Thread 9):
16:34:45,826 DEBUG [http-bio-8080-exec-3] cache.StandardQueryCache:(StandardQueryCache.java:96) - caching query results in region: org.hibernate.cache.StandardQueryCache; timestamp=5466792287543296
Thus at this point of time deleted ID will be in query cache and query cache will be considered as being up to date.
16:34:45,852 DEBUG [http-bio-8080-exec-9] cache.UpdateTimestampsCache:(UpdateTimestampsCache.java:122) - [virtual_device_class] last update timestamp: 5466792287494145, result set timestamp: 5466792287543296
So when you try to get lookups again it will look in query cache and then will start materializing entities from the second cache.
16:34:45,852 DEBUG [http-bio-8080-exec-9] cache.StandardQueryCache:(StandardQueryCache.java:140) - returning cached query results
But deleted item won't be there, so query to db will be done.
16:34:45,863 DEBUG [http-bio-8080-exec-9] loader.Loader:(Loader.java:2022) - loading entity: [com.test.models.VirtualDeviceClass#0b2f363f-fbb9-4d17-8f86-af86ebb5100c]
16:34:45,873 DEBUG [http-bio-8080-exec-9] hibernate.SQL:(SQLStatementLogger.java:111) - select virtualdev0_.virtual_device_class_id as virtual1_45_0_, virtualdev0_.virtual_device_class as virtual2_45_0_, virtualdev0_.sitebox_id as sitebox3_45_0_, virtualdev0
As I am using Load method so it throws exception if entity is not found in db.
in my case entities would be rarely updated it might happen and that's worrying me. I've got few ideas how to try to overcome this issue:
a) set trx isolation level to Repeatable Read in DB (however do not think that it will help because adding to cache logic takes place after reading data from db)
b) manually force Standard Query Cache to evict on entity delete/update
c) do not use query cache at all (try to route most of db queries to use second cache)
Did anybody face with this issue before?
I have migrated to Hibernate 4 and it works fine now.
This issue might have been related to synchronized block being removed in method SessionFactory.getQueryCache(String regionName)
link to hibernate issue

Categories