public interface SyncResolver
定义一个框架,当发生同步冲突时,它允许应用程序使用手工决策树来确定应该执行的操作。虽然应用程序手工解决同步冲突并不是委托过程,但此框架还是提供了一些发生冲突时委托应用程序的方法。
注意,冲突是指 RowSet
对象的原始行值与数据源中的值不匹配的情况,它指示自最后一次同步以来数据源行已被修改。还要注意,RowSet
对象的原始值就是最后一次同步之前的值,不必是其初始值。
SyncResolver
对象的描述SyncResolver
对象是实现
SyncResolver
接口的专用
RowSet
对象。它
可以以连接的
RowSet
对象(
JdbcRowSet
接口的实现)或非连接
RowSet
对象(
CachedRowSet
接口或其一个子接口的实现)的形式进行操作。有关子接口的信息,请参阅
javax.sql.rowset
包描述。
SyncResolver
的参考实现实现了
CachedRowSet
接口,但是其他实现可以选择实现
JdbcRowSet
接口,以满足特定的需要。
应用程序尝试使 RowSet
对象与数据源同步(通过调用 CachedRowSet
方法 acceptChanges
),并且找到一个或多个冲突之后,rowset 的 SyncProvider
对象会创建一个 SyncResolver
实例。这一新的 SyncResolver
对象具有与正在尝试同步的 RowSet
对象相同的行数和列数。SyncResolver
对象包含数据源中导致冲突的值,其他值都为 null
。另外,它包含关于每个冲突的信息。
SyncResolver
对象acceptChanges
遇到冲突时,
SyncProvider
对象会创建
SyncProviderException
对象,并使用新的
SyncResolver
对象设置它。方法
acceptChanges
将抛出此异常,然后应用程序可以捕获它并用以获取它包含的
SyncResolver
对象。以下代码片段使用
SyncProviderException
方法
getSyncResolver
来获取
SyncResolver
对象
resolver。
} catch (SyncProviderException spe) { SyncResolver resolver = spe.getSyncResolver(); ... }
通过所拥有的 resolver,应用程序可以使用它获取关于冲突的信息。SyncResolver
对象(如 resolver)跟踪存在冲突的每个行中的冲突。它还可以锁定受 rowset 命令影响的表,以便在解决当前冲突时不再发生其他冲突。
可以从 SyncResolver
对象获取以下几种信息:
SyncProvider
接口定义了四个常量来描述可能发生的状态。其中三个常量描述发现冲突时 RowSet
对象正试图执行的操作类型(更新、删除或插入),第四个常量指示不存在冲突。当 SyncResolver
对象调用方法 getStatus
时,这些常量都是可能的返回值。 int operation = resolver.getStatus();
RowSet
对象更改并尝试写入到数据源的值自上一次同步以来也在数据源中被更改时,会发生冲突。应用程序可以调用 SyncResolver
的方法 getConflictValue
来获取数据源中导致冲突的值,因为 SyncResolver
对象中的值是取自数据源的冲突值。 java.lang.Object conflictValue = resolver.getConflictValue(2);注意,resolver 中的列可以使用列号指定(如以上代码行中所示),也可以用列名称指定。
使用从方法 getStatus
和 getConflictValue
获取到的信息,应用程序可以做出应在数据源中保留哪一个值的决定。然后,应用程序调用 SyncResolver
的方法 setResolvedValue
,它可以设置 RowSet
对象中和数据源中要保留的值。
resolver.setResolvedValue("DEPT", 8390426);在以上代码行中,列名称指定
RowSet
对象中要使用给定值设置的列。也可以用列号来指定列。 解决当前冲突行中的所有冲突之后,应用程序会调用方法 setResolvedValue
,并对 SyncResolver
对象中每个冲突行重复此过程。
SyncResolver
对象SyncResolver
对象是 RowSet
对象,所以应用程序可以使用所有的 RowSet
方法移动指针来导航 SyncResolver
对象。例如,应用程序可以使用 RowSet
的方法 next
到达每个行,然后调用 SyncResolver
的方法 getStatus
查看行是否包含冲突。在具有一个或多个冲突的行中,应用程序可以迭代列来查找任何非 null 值,它将是数据源中处于冲突状态的值。 要使导航 SyncResolver
对象更容易,尤其是存在大量没有冲突的行时,SyncResolver
接口定义了方法 nextConflict
和 previousConflict
,它们只移动到至少包含一个冲突值的行。然后,应用程序通过提供列号作为参数调用 SyncResolver
的方法 getConflictValue
,以获取冲突值本身。下一节中的代码片段给出了一个示例。
RowSet
对象 crs 如何尝试使自已与底层数据源同步,然后解决冲突。在 try
块中,crs 调用方法 acceptChanges
,将 Connection
对象 con 传递给它。如果不存在冲突,则将 crs 中的更改写入到数据源即可。但是,如果存在冲突,则方法 acceptChanges
将抛出 SyncProviderException
对象,catch
块生效。在此示例中,阐述了多种 SyncResolver
对象使用方式中的一种,在 while
循环中,使用 SyncResolver
的方法 nextConflict
。nextConflict
返回 false
时循环将终止,这发生在 SyncResolver
对象 resolver 中不再有冲突行时。在此特定的代码片段中,resolver 查找有更新冲突的行(状态为 SyncResolver.UPDATE_ROW_CONFLICT
的行),此代码片段其余部分仅执行由于 crs 尝试更新而发生冲突的行。 resolver 的指针移动到有更新冲突的下一个冲突行之后,方法 getRow
指示当前行的数字,并且将 CachedRowSet
对象 crs 的指针移到 crs 中的对等行。通过迭代 resolver 和 crs 中行的列,可以获取和比较冲突值,以确定应保留哪一个值。在此代码片段中,crs 中的值是设置为解决值的值,这意味着它将用于重写数据源中的冲突值。
try { crs.acceptChanges(con); } catch (SyncProviderException spe) { SyncResolver resolver = spe.getSyncResolver(); Object crsValue; // value in theRowSet
object Object resolverValue: // value in theSyncResolver
object Object resolvedValue: // value to be persisted while(resolver.nextConflict()) { if(resolver.getStatus() == SyncResolver.UPDATE_ROW_CONFLICT) { int row = resolver.getRow(); crs.absolute(row); int colCount = crs.getMetaData().getColumnCount(); for(int j = 1; j <= colCount; j++) { if (resolver.getConflictValue(j) != null) { crsValue = crs.getObject(j); resolverValue = resolver.getConflictValue(j); . . . // compare crsValue and resolverValue to determine // which should be the resolved value (the value to persist) resolvedValue = crsValue; resolver.setResolvedValue(j, resolvedValue); } } } } }
字段摘要 | |
---|---|
static int |
DELETE_ROW_CONFLICT 指示在 RowSet 对象试图删除数据源中的行时发生冲突。 |
static int |
INSERT_ROW_CONFLICT 指示在 RowSet 对象试图将行插入数据源中时发生冲突。 |
static int |
NO_ROW_CONFLICT 指示在 RowSet 对象试图更新、删除或插入数据源中的行时不发生任何冲突。 |
static int |
UPDATE_ROW_CONFLICT 指示在 RowSet 对象试图更新数据源中的行时发生冲突。 |
方法摘要 | |
---|---|
Object |
getConflictValue(int index) 获取此 SyncResolver 对象的当前行中指定列的值,它是数据源中导致冲突的值。 |
Object |
getConflictValue(String columnName) 获取此 SyncResolver 对象的当前行中指定列的值,它是数据源中导致冲突的值。 |
int |
getStatus() 获取此 SyncResolver 的当前行的冲突状态,它指示在发生冲突时 RowSet 对象正尝试的操作。 |
boolean |
nextConflict() 将指针从其当前位置移动到下一个包含冲突值的行。 |
boolean |
previousConflict() 将指针从其当前位置移动到此 SyncResolver 对象中上一个冲突行。 |
void |
setResolvedValue(int index, Object obj) 将 obj 设置为将同步的 RowSet 对象当前行中第 index 列的值。 |
void |
setResolvedValue(String columnName, Object obj) 将 obj 设置为将同步的 RowSet 对象当前行中列 columnName 的值。 |
从接口 java.sql.Wrapper 继承的方法 |
---|
isWrapperFor, unwrap |
字段详细信息 |
---|
static final int UPDATE_ROW_CONFLICT
RowSet
对象试图更新数据源中的行时发生冲突。数据源行中要更新的值不同于该行的
RowSet
对象的原始值,这意味着自上一次同步以来已更新或删除了数据源中的行。
static final int DELETE_ROW_CONFLICT
RowSet
对象试图删除数据源中的行时发生冲突。数据源行中要更新的值不同于该行的
RowSet
对象的原始值,这意味着自上一次同步以来已更新或删除了数据源中的行。
static final int INSERT_ROW_CONFLICT
RowSet
对象试图将行插入数据源中时发生冲突。这意味着自上一次同步以来已经在数据源中插入了一个与要插入的行具有相同主键的行。
static final int NO_ROW_CONFLICT
RowSet
对象试图更新、删除或插入数据源中的行时
不发生任何冲突。
SyncResolver
中的值将包含
null
值,该值仅指示此行中没有关于冲突解决的信息。
方法详细信息 |
---|
int getStatus()
SyncResolver
的当前行的冲突状态,它指示在发生冲突时
RowSet
对象正尝试的操作。
SyncResolver.UPDATE_ROW_CONFLICT
、
SyncResolver.DELETE_ROW_CONFLICT
、
SyncResolver.INSERT_ROW_CONFLICT
或
SyncResolver.NO_ROW_CONFLICT
Object getConflictValue(int index) throws SQLException
SyncResolver
对象的当前行中指定列的值,它是数据源中导致冲突的值。
index
- 一个
int
,它指定此
SyncResolver
对象的此行中的列,从该列可以获取导致冲突的值
SyncResolver
对象的当前行中指定列的值
SQLException
- 如果发生数据库访问错误
Object getConflictValue(String columnName) throws SQLException
SyncResolver
对象的当前行中指定列的值,它是数据源中导致冲突的值。
columnName
-
String
对象,它指定此
SyncResolver
对象的此行中的列,从该列可以获取导致冲突的值
SyncResolver
对象的当前行中指定列的值
SQLException
- 如果发生数据库访问错误
void setResolvedValue(int index, Object obj) throws SQLException
RowSet
对象当前行中第
index 列的值。将
obj 内部地设置为数据源中的值。
index
- 一个
int
,它提供要设置保留值的列号
obj
- 一个
Object
,它是在
RowSet
对象中设置的值,将它保留在数据源中
SQLException
- 如果发生数据库访问错误
void setResolvedValue(String columnName, Object obj) throws SQLException
RowSet
对象当前行中列
columnName 的值。将
obj 内部地设置为数据源中的值。
columnName
-
String
对象,它提供要设置保留值的列名称
obj
- 一个
Object
,它是在
RowSet
对象中设置的值,将它保留在数据源中
SQLException
- 如果发生数据库访问错误
boolean nextConflict() throws SQLException
SyncResolver
对象的指针最初位于第一个冲突行之前;第一次调用
nextConflict
方法使第一个冲突行成为当前行;第二次调用使第二个冲突行成为当前行,依此类推。
调用方法 nextConflict
将隐式关闭输入流(如果有打开的输入流),并且将清除 SyncResolver
对象的警告链。
true
;如果不存在下一行,则返回
false
SQLException
- 如果发生数据库访问错误,或者结果集类型为
TYPE_FORWARD_ONLY
boolean previousConflict() throws SQLException
SyncResolver
对象中上一个冲突行。
调用方法 previousConflict
将隐式关闭输入流(如果有打开的输入流),并且将清除 SyncResolver
对象的警告链。
true
;如果它不在结果集中,则返回
false
SQLException
- 如果发生数据库访问错误,或者结果集类型为
TYPE_FORWARD_ONLY