这章将讨论怎样使用缓存集合。
使用ALTER CACHE GROUP语句来改变AUTOREFRESH STATE、INTERVAL和MODE的设置。任何通过ALTER CACHE GROUP设置的值或状态都是永久的;它们保存在数据存储中,并在TimesTen守护程序和缓存代理重新启动时生存。
注意:如果TimesTen安装时Access Control被激活,则必须拥有DDL权限来在数据存储中使用ALTER CACHE GROUP语句。
当一个AUTOREFRESH操作正在进行中并且将STATE改为OFF:
• 如果LockWait普通连接属性大于0,则AUTOREFRESH操作将停止。ALTER CACHE GROUP SET AUTOREFRESH STATE OFF语句优先于AUTOREFRESH操作。
• 如果LockWait普通连接属性为0,则AUTOREFRESH操作将继续。ALTER CACHE GROUP SET AUTOREFRESH STATE OFF语句将失败,产生一个锁定终止错误。
例 5.1此例通过将状态改为ON来激活AutorefreshCustomers缓存集合的AUTOREFRESH:
ALTER CACHE GROUP AutorefreshCustomers
SET AUTOREFRESH STATE ON;
使用DROP CACHE GROUP SQL语句来从TimesTen中删除缓存集合和它所有相关的表。
注意:如果TimesTen安装时Access Control被激活,则必须拥有DDL权限来在数据存储中使用DROP CACHE GROUP语句。
如果删除使用了以INCREMENTAL模式的AUTOREFRESH并在Oracle进行手工安装对象的READONLY缓存集合或USERMANAGED缓存集合,则在删除缓存集合之前,必须手工删除Oracle对象。
当一个AUTOREFRESH操作正在进行时,如果输入一条DROP CACHE GROUP语句:
• 如果LockWait普通连接属性大于0,则AUTOREFRESH操作将停止。DROP CACHE GROUP语句优先于AUTOREFRESH操作。
• 如果LockWait普通连接属性为0,则AUTOREFRESH操作将继续。DROP CACHE GROUP语句将失败,产生一个锁定终止错误。
为了删除WesternCustomers缓存集合:
DROP CACHE GROUP WesternCustomers
所有WesternCustomers缓存中表将立即从TimesTen中被删除,并且缓存集合的定义也将从TimesTen系统表中被删除。
注意:所有AWT设置都将保持有效,直到DROP CACHE GROUP事务被提交。如果缓存集合是AWT,在删除缓存集合之前,确保所有绑定的更新都已经应用到Oracle。使用ttRepSubscriberWait程序。
TimesTen多个机制来从Oracle拷贝数据到TimesTen和从TimesTen拷贝数据到Oracle。
一个应用可以使用下列SQL语句来在Oracle和缓存集合之间拷贝数据:
SQL语句 |
描述 |
LOAD CACHE GROUP |
从Oracle 数据中加载还没有在缓存中的缓存实例。 |
REFRESH CACHE GROUP |
使用当前的Oracle数据替换缓存实例。 |
FLUSH CACHE GROUP |
从缓存集合表中拷贝数据到Oracle表。缓存集合必须是PROPAGATE没有激活的USERMANAGED。 |
PROPAGATE被激活的SWT缓存集合、AWT缓存集合和USERMANAGED缓存集合提供了自动方式来将缓存集合中的更新应用到Oracle表。
AUTOREFRESH缓存集合属性可用于READONLY和USERMANAGED缓存集合中来自动将Oracle表中变化应用到缓存集合中。
当一条SELECT查询在缓存集合表中没有找到数据时,可以使用事务加载特性来将Oracle表中的数据加载到缓存集合表中。可以对除了使用AUTOREFRESH属性以外的所有缓存集合使用事务加载。
AUTOREFRESH是一个缓存集合定义的一部分。在已经定义缓存集合并按需调用之后,事务加载就可以实现。事务加载与AUTOREFRESH缓存集合相比较,前者在缓存集合上的限制较少。
AUTOREFRESH适用于与静态数据相关的如产品目录或飞行航班表。事务加载在动态缓存内容方面更有用。应用可以使用事务加载特性来加载数据到缓存中,并使TimesTen代理自动删除长时间没有使用的数据。
可以使用一条LOAD CACHE GROUP或REFRESH CACHE GROUP语句来将数据从Oracle加载到缓存集合中。两种从Oracle拷贝数据到缓存集合的SQL语句都可以含或不含WHERE子句或WITH ID子句。加载和刷新的有如下不同:
• LOAD CACHE GROUP 不更新已经出现在缓存集合中的实例。
• REFRESH CACHE GROUP 使用最近的Oracle数据替换缓存集合中所有或指定的实例,即使实例已经出现在缓集合中。自动刷新操作相当于一条UNLOAD CACHE GROUP 语句后跟一条LOAD CACHE GROUP 语句。所有到Oracle数据的变化,包括根表和子表中的插入、更新和删除,将在刷新操作后反映到缓存中。
例 5.2为了从Oracle加载数据到WesternCustomers缓存集合:
LOAD CACHE GROUP WesternCustomers
COMMIT EVERY 256 ROWS;
例 5.3为了只从Oracle中加载Zip Code 94022中的用户的缓存集合实例到WesternCustomers缓存集合:
LOAD CACHE GROUP WesternCustomers
WHERE (user1.customer.zip = 94022)
COMMIT EVERY 256 ROWS;
例 5.4为了从Oracle表中刷新整个WesternCustomers缓存集合:
REFRESH CACHE GROUP WesternCustomers
COMMIT EVERY 256 ROWS;
例 5.5为了只刷新与合同号2353相关的缓存集合实例:
REFRESH CACHE GROUP WesternCustomers
WHERE (user1.orderdetails.itemid = 2353)
COMMIT EVERY 256 ROWS;
加载和刷新AUTOREFRESH和READONLY缓存集合有如下限制:
• 加载一个AUTOREFRESH呀READONLY缓存集合时,缓存集合必须为空。
• AUTOREFRESH状态必须是PAUSED。
• LOAD或REFRESH语句不能包含WHERE子句或WITH ID子句。
执行下列任务来加载一个AUTOREFRESH缓民集合:
1. 设置AUTOREFRESH状态为PAUSED。
ALTER CACHE GROUP testcache SET AUTOREFRESH STATE PAUSED;
COMMIT;
2. 卸载缓存集合。
UNLOAD CACHE GROUP testcache;
COMMIT;
3. 加载缓存集合。
LOAD CACHE GROUP testcache COMMIT EVERY 256 ROWS;
COMMIT;
4. 设置AUTOREFRESH状态为ON。
ALTER CACHE GROUP testcache SET AUTOREFRESH STATE ON;
COMMIT;
WITH ID子句能够根据主键的值而不需要WHERE子句来加载或刷新一个缓存集合。可以以字段名或绑定参数来描述主键值。使用WITH ID子句将比使用等价的WHERE子句速度要快。如果失败,也能够回滚加载的事务。
WITH ID子句不能用于AUTOREFRESH或READONLY缓存集合。
WITH ID子句允许每次加载一个缓存实例。假设有一个orders表,其主键为order_id。如果用户调用一指定的合同,则可以通过为指定的order_id加载缓存实例加载相关信息。
例 5.6在Oracle中,创建一名为sample的表:
CREATE TABLE sample (a NUMBER, b NUMBER, c NUMBER,
PRIMARY KEY (a,b));
缓装此表以使它包含以下行:
A B C
---------- ---------- ----------
1 2 3
4 5 6
7 8 9
在TimesTen上创建缓存集合:
CREATE SYNCHRONOUS WRITETHROUGH CACHE GROUP testcache
FROM sample
(a NUMBER, b NUMBER, c NUMBER, PRIMARY KEY (a,b));
使用主键有值(1,2)的行加载缓存集合:
LOAD CACHE GROUP testcache WITH ID (1,2);
1 cache instance affected.
SELECT * FROM sample;
< 1, 2, 3>
1 row found.
例 5.7使用主键有值(4,5)的行刷新testcache缓存集合:
REFRESH CACHE GROUP testcache WITH ID (4,5);
1 cache instance affected.
SELECT * FROM sample;
< 1, 2, 3 >
< 4, 5, 6 >
2 rows found.
如果缓存集合包含多个表,并且Oracle当前正在更新被加载或刷新的表,在提交LOAD CACHE GROUP或REFRESH CACHE GROUP语句之前,可以设置TimesTen isolation级别为SERIALIZABLE。这将使TimesTen以连接的方式来查询Oracle表,并保证加载的数据与事务一致。在已经加载或刷新缓存集合之后,可以为更好的并发重新设置isolation级别为READ_COMMITTED。
例 5.8在一个ttIsql会话中,在加载缓存集合之前可以重新设置isolation级别。当要加载或刷新缓存集合时,这个将应用到非日志模式。
Command> isolation SERIALIZABLE;
Command> LOAD CACHE GROUP WesternCustomers
>COMMIT EVERY 1000 ROWS;
Command> isolation READ_COMMITTED;
可以通过使用LOAD CACHE GROUP或REFRESH CACHEGROUP语句的PARALLEL子句来改善加载或刷新大表的执行速度。指定要使用的线程号。一个线程从Oracle中取出行,并且另外一个线程插入数据到缓存集合中。不要指定大于CPU能够加载的线程数量。
例 5.9
REFRESH CACHE GROUP WesterCustomers
COMMIT EVERY 256 ROWS
PARALLEL 2;
当一条SELECT查询在缓存集合中没有查找到数据时,可以配置TimesTen来自动从Oracle表中加载数据到缓存集合表中。当执行SELECT语句时,被选择的和相关的行被加载到缓存集合的根表中,并且关联和被选择的行也被加载到子表中。只有那些满足缓存集合定义的行被加载。如果缓存集合有基于时间的老化性质定义,这些行也必须满足此老化性质。
可以为所有的类型的缓存集合配置透明加载,除了使用AUTOREFRESH属性的READONLY缓存集合和USERMANAGED缓存集合。
当缓存内容是动态的情况下,透明加载特别有用。例如,可以使用它来加载已经被老化删除的数据。
透明加载可用于下列类型的SELECT语句:
• SELECT在单表的主键上使用了一个等价的条件。此等价条件必须包括一个常量或参数。例如:
SELECT * FROM table1 WHERE primkey=1;
如果主键是复合键,则SELECT语句必须包括所有主键列的等价条件。例如:
SELECT * FROM table2 WHERE pkcol1=10 AND pkcol2=10;
• SELECT在单表的外键上使用了一个等价的条件。此等价条件必须包括一个常量或参数。例如:
SELECT * FROM table2 WHERE foreignkey=1;
如果外键是复合键,则SELECT语句必须包括所有外键列的等价条件。例如:
SELECT * FROM table2 WHERE fkcol1=10 AND fkcol2=10;
• 使用一个等价的条件选择缓存集合实例中的一个子树。例如:
SELECT * FROM table1,table2 where table1.primkey=1 and
table2.foreignkey=table1.primkey;
SELECT查询必须满足下列条件:
• SELECT查询必须是语句中最外层的查询。
• SELECT查询不能包含UNION、INTERSECT或MINUS结果集操作。
• 只有一个缓存集合中的表可以指定在最外层的SELECT查询中,但其它没有在缓存集合中的表可以指定在语句中。
当SELECT查询返回选择的行时,整个缓存实例都要被加载,以保持主键和外键之间的关联。.
为了透明加载数据,设置TransparentLoadCache Connect属性为1。这将使一条SELECT语句在Oracle表上被执行。数据结果将被加载到缓存集合表中。然后此数据通过在缓存集合表中执行原来的SELECT语句被透明返回。
下表总结关于TransparentLoad的设置:
设置 |
描述 |
0 |
不使用透明加载。(缺省) |
1 |
在TimesTen中不发送错误信息或警告信息的运行SELECT语句。 |
2 |
如果SELECT操作不能使用透明加载,将返回一个错误。将根据TimesTen中可用的数据来执行SELECT操作。 |
二选其一,为了能够使用透明加载,可以使用SQLSetConnectOptionODBC函数来设置TT_TRANSPARENT_LOAD ODBC连接选项。此设置将应用到整个连接。
可以通过使用ttOptSetFlag内部程序的TransparentLoad标志来覆盖指定事务的TransparentLoad属性或TT_TRANSPARENT_LOAD ODBC选项。当语句准备时,TransparentLoad标志值就将产生影响,并且在运行时不能进行改变。在事务被提交或回滚时之后,此连接属性将重新产生影响。
FLUSH CACHE GROUP语句将USERMANAGED缓存集合中的插入和更新冲洗到Oracle。不冲洗删除。指定为READONLY或PROPAGATE的表中的记录也不会冲洗到Oracle。
当从TimesTen到Oracle的数据提交被关闭时,使用FLUSH CACHE GROUP。相比每次事务提交更新数据,在更新被传送到Oracle之前,许多事务可以在TimesTen中被提交会更好。对于每个实例,如果缓存实例在Oracle中存在,则Oracle中操作将由一个更新构成。如果缓存实例在Oracle不存在,则TimesTen将插入它。
FLUSH CACHE GROUP语句可以使用WHERE或WITH ID子句指定以控制冲洗到Oracle的数据。
例 5.10为了将WesternCustomers缓存集合中的变化冲洗到Oracle:
FLUSH CACHE GROUP WesternCustomers;
可以使用UNLOAD CACHE GROUP SQL语句来删除缓存集合中一些或所有的实例。与DROP CACHE GROUP语句不同,它们中的表不会被删除。
对于使用AUTOREFRESH属性的缓存集合要小心使用UNLOAD CACHE GROUP语句。如果行或它的子行在Oracle中被更新,作为自动刷新的结果,被卸载的行有可能再次出现在缓存集合中。
例 5.11为了从WesternCustomers缓存中删除所有实例:
UNLOAD CACHE GROUP WesternCustomers;
为了从WesternCustomers缓存中删除CustId = 1的用户:
UNLOAD CACHE GROUP WesternCustomers WITH ID(1);
或
UNLOAD CACHE GROUP WesternCustomers
WHERE (User1.Customer.CustId = 1);
可以从一个数据存储中复制缓存集合表到另一个数据存储中的缓存集合表中或另一个数据存储的标准TimesTen表中。主数据存储中的缓存集合类型必须与子数据存储中的缓存集合类型相同。例如,READONLY缓存集合中的表可只能被复制到另一个数据存储中的READONLY缓存集合的表中或另一个数据存储的标准TimesTen表中。
缓存集合中的所有表都必须包括在复制计划中。
可以为下列类型的缓存集合通过配置一个名为active standby pair的复制计划来实现高效的缓存实例:
• READONLY缓存集合
• ASYNCHRONOUS WRITETHROUGH缓存集合
一个复制这些类型之一的缓存集合活动备用对可以自动地改变缓存集合的角色作为失败和使用最小数据丢失进行恢复的一部分。缓存集合给自己提供来自于Oracle数据库的弹性,进一步巩固系统的可靠性。
也可以配置缓存集合表的复制来实现工作量的平衡。下面的配置是一个示例:
• 加载平衡 — 配置从使用AUTOREFRESH属性的缓存集合中的表到标准表中的单向复制。Oracle上的更新将自动刷新到TimesTen缓存集合。此更新然后被复制到TimesTen表。
• 分隔工作量 — 在不同的数据存储的WRITETHROUGH缓存集合中的表之间配置双向复制。设计应用以使事务为了一个特定用途(例如,一个地理区域)只更新特定的缓存数据表,并且相同的缓存集合表不能在两个存储中都直接被更新。在一个存储中被更新的缓存集合表被复制到另一个数据存储中相应的缓存集合表中。更新将直接通过应用传送到Oracle,但不进行复制更新。
不要使用活动active/活动配置,特别是复制缓存集合时。这种配置的非预期结果包括不可解的死锁、缓存集合内容的冲突和恢复问题。
Cache Connect to Oracle没有机制来发现Oracle数据库由际操作如CREATE、DROP或ALTER引起的规划改变。如果需要改变Oracle规划,则要执行下列任务:
1. 使用DROP CACHE GROUP来删除所有缓存Oracle被改变表的缓存集合。
2. 停止缓存代理。
3. 对Oracle进行期望的改变。
4. 使用CREATE CACHE GROUP来重新创建缓存集合。
如果在Oracle数据库中规划被修改之前不删除缓存集合,则在原来缓存集合中的操作,包括AUTOREFRESH,可能成功,也可能失败而产生错误。
增量AUTOREFRESH不能发现一人Oracle表的截短。如果要截短一个Oracle基表,则要执行下列任务:
1. 使用ALTER CACHE GROUP语句来设置AUTOREFRESH STATE为PAUSED。
2. 截短Oracle基表。
3. 通过使用不带有WHERE或WITH ID子句的REFRESH CACHE GROUP语句刷新缓存集合。
在刷新缓存集合之后,自动刷新操作将重新开始。
注意:在缓存集合中不允许截短TimesTen表。
注意:如果缓存集合是AWT,在删除缓存集合之前,确保所有绑定的更新已经应用到Oracle。使用ttRepSubscriberWait程序。