关于查询不能获取数据库最新数据有关问题
最近发现在做Java项目时,获取数据库连接,分别进行了2次不同的查询,在第二次查询之前将数据库进行更新,执行查询后获取不到最新的数据信息。
针对这个问题,大多人首先考虑的是缓存问题,然而禁止了一级缓存和二级缓存仍然解决不了目前的问题。这时候多数人不知道如何下手了,针对这个问题应该如何解决呢?
首先hibernate自带的缓存机制,做的还不够完善,不能实时获取最新的数据信息,你可以考虑换一个与数据库交互的连接,比如c3p0或者bonecp,配置如下:
C3P0配置:
需要导入3个jar包,分别是:c3p0-0.9.2.1.jar hibernate-c3p0-4.3.5.Final.jar
mchange-commons-java-0.2.3.4.jar
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="minPoolSize" value="10" /> //在连接池中可用数据库连接的最小数目
<property name="maxPoolSize" value="100" /> //在连接池中所有数据库连接的最大数目
<property name="maxIdleTime" value="120" /> //最大空闲时间,120秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0
<property name="acquireIncrement" value="3" /> //当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3
<property name="maxStatements" value="50" /> //可以被缓存的PreparedStatement的最大数目
<property name="initialPoolSize" value="20" /> //初始化时获取连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3
<property name="idleConnectionTestPeriod" value="60" /> //每60秒检查所有连接池中的空闲连接。Default: 0
<property name="acquireRetryAttempts" value="30" /> //定义在从数据库获取新连接失败后重复尝试的次数。Default: 30
<property name="breakAfterAcquireFailure" value="true"/>
<property name="testConnectionOnCheckout" value="false"/>
</bean>
BoneCP配置如下:
需要导入的jar包: bonecp-0.7.1.RELEASE.jar google-collections-1.0.jar,slf4j-api-1.5.8.jar,slf4j-log4j12-1.5.6.jar和slf4j-simple-1.5.8.jar
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="idleConnectionTestPeriod" value="${bonecp.idleConnectionTestPeriod}"/>
<property name="idleMaxAge" value="${bonecp.idleMaxAge}"/>
<property name="maxConnectionsPerPartition" value="${bonecp.maxConnectionsPerPartition}"/>
<property name="minConnectionsPerPartition" value="${bonecp.minConnectionsPerPartition}"/>
<property name="partitionCount" value="${bonecp.partitionCount}"/>
<property name="acquireIncrement" value="${bonecp.acquireIncrement}"/>
<property name="statementsCacheSize" value="${bonecp.statementsCacheSize}"/>
<property name="releaseHelperThreads" value="${bonecp.releaseHelperThreads}"/>
</bean>
通过C3P0 和 BoneCP连接数据库能够实时获取到数据库的最新数据信息了。
然而还有一些例外情况,仍然获取不到数据库的最新数据信息,现在有两种解决方式:
第一种:断开与数据库连接的session,在执行查询,实验证明是可以获取到最新数据信息,如下:
Session session=sessionFactory.getCurrentSession();
session.disconnect();
Map<String,String> paramMap=new FastMap().newHashMap().set("conid", list.get(0));
MsRealdata realdata=selSer.findOne("realdata.findMsRealdata",null);
Connection conn=DBManager.getConnection();
session.reconnect(DBManager.getConnection());
conn.setAutoCommit(false);
其中先断开session连接一个很短暂的时间,执行查询之后再连接上,realdata获取的是最新的数据信息。
第二种:需要从数据库入手,以Mysql数据库为例
执行一个查询
mysql> show variables
like
'%iso%'
;
+
---------------+-----------------+
| Variable_name | Value |
+
---------------+-----------------+
| tx_isolation |
REPEATABLE
-
READ
|
+
---------------+-----------------+
1 row
in
set
(0.00 sec)
如果是上面这样的,执行下面的SQL
mysql>
set
global
TRANSACTION
ISOLATION
LEVEL
READ
COMMITTED
;
Query OK, 0
rows
affected (0.00 sec)
再次执行查询
mysql> show variables
like
'%iso%'
;
+
---------------+-----------------+
| Variable_name | Value |
+
---------------+-----------------+
| tx_isolation |
REPEATABLE
-
READ
|
+
---------------+-----------------+
1 row
in
set
(0.00 sec)
mysql> show
global
variables
like
'%iso%'
;
+
---------------+----------------+
| Variable_name | Value |
+
---------------+----------------+
| tx_isolation |
READ
-
COMMITTED
|
+
---------------+----------------+
1 row
in
set
(0.00 sec)
如果改变后的结果如上,则恭喜你,解决问题了。