4

我正在通过 JNDI 资源使用 tomcat 连接池。

context.xml

<Resource name="jdbc/mydb" auth="Container" type="javax.sql.DataSource"
          username="myusr" password="mypwd" driverClassName="com.mysql.jdbc.Driver"
          maxActive="1000" maxIdle="100" maxWait="10000"
          url="jdbc:mysql://localhost:3306/mydatabase" 
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" />

web.xml

<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/mydb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

数据库是 MySQL 的。

当我选择一些信息时,例如产品列表,在插入或删除产品后也会显示相同的列表。

如何防止这种情况?在这种情况下,我会看到更新的列表。

编辑

query_cache_size0 且query_cache_type为 ON。

那么,问题可能出在哪里?为什么会发生查询缓存?

编辑

我读到了“RESET QUERY CACHE”和“FLUSH TABLES”。

它们之间有什么区别?

通过使用其中之一,拍卖/电子商务场景中是否会出现问题?

4

3 回答 3

6

一致非锁定读取下所述:

如果事务隔离级别REPEATABLE READ(默认级别),则同一事务中的所有一致性读取都会读取该事务中第一次此类读取所建立的快照。您可以通过提交当前事务并在此之后发出新查询来获得查询的更新快照。

[删除]

如果您想查看数据库的“最新”状态,请使用READ COMMITTED隔离级别或锁定读取

SELECT * FROM t LOCK IN SHARE MODE;

您可以通过其Resource@defaultTransactionIsolation属性设置 Tomcat 中的默认事务隔离级别。

于 2013-07-11T09:00:32.320 回答
1

RESET QUERY CACHE只清除查询缓存。

FLUSH TABLES关闭所有表(在刷新任何未写入的数据之后)并清除查询缓存。

清除缓存不会导致您遇到的问题。它所做的只是强制后续查询实际从表中获取数据(直到这些结果再次被缓存)。

请注意,查询缓存保证永远不会显示过时的数据。对缓存中查询引用的任何表的任何已提交写入都会从缓存中删除此类查询。如果您看到过时的数据,则必须使用另一种外部机制。例如,许多 ORM 在某个阶段会进行一些行缓存,并且这种机制可能会被破坏,或者如果没有完全按照预期使用可能会产生意想不到的结果。

无论如何,如果是query_cache_size = 0query_cache_type = OFF(或0),则禁用查询缓存。

于 2013-07-10T12:20:37.443 回答
1

连接池与数据缓存没有任何关系(除非您专门以这种方式配置它)。最佳实践是使用连接池进行数据库访问,以防止连接失控(例如,同时连接过多的数据库)并重用已打开一次的连接(通常建立连接非常昂贵,因此它们会再次被利用) . 您还希望语句本身(as PreparedStatement)被缓存,因为数据库的下一个昂贵操作是确定执行计划。(这与实际结果缓存无关)

您是否分析过您的缓存数据是否真的来自 mysql,或者您是否在应用程序级别进行缓存?

另外,请确保您的insert&update事务实际上已提交,否则显然不会有任何更改,并且数据看起来像是已缓存。

于 2013-06-10T13:51:47.033 回答