AM使用指南之二:Nested AM与Root AM之间的Transaction关系
来源:互联网 发布:大学校园网络营销策划 编辑:程序博客网 时间:2024/05/22 15:14
开发环境:JDeveloper 11.1.2.2.0 + Oracle XE Database 10gR2。
在实际应用中,为了达到逻辑重用的目的,会使用嵌套的AM。
在Root AM和Nested AM中都有各自的VO,在一个页面中,可能同时用到了不同AM的不同的VO,那么当一个AM提交时,另一个AM是否也会提交呢?
其实,这个问题的产生来自于一个客户的真实情况:
在一个页面中,有多个Tab页签,每个Tab页签中都一个表单和保存按钮。
用户可以选择修改Tab页签中的表单,于是就出现了这种情况:
用户修改了某个Tab页签中的表单,没有马上提交,接着修改另一个Tab页签中的表单,并点击这个Tab页签中的保存按钮,结果发现前一个页签中的修改也被成功提交了。
为了更加清楚阐述这个问题,我做了一个实验。
实验步骤主要如下:
1. 创建并定制化AppModule,包含JobVO和EmployeeVO。
增加3个方法,代码如下:
2. 创建并定制化NestedAppModule,包含JobVO。
(1)创建
(2)定制化
增加2个方法,代码和AppModule前2个方法相同,略。
3. 把NestedAppModule加入到AppModule中。
(1)
(2)完成后的Data Control
4. 创建页面,内容如下:
(1)拖放root AM DC中的JobView1和EmployeeView1,都选择Form。
(2)为Job Form 添加两个Button: Create和Delete。代码如下:
public String rootAMCreate_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
service.createJob();
return null;
}
public String rootAMDelete_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
service.deleteJob();
return null;
}
(3)为Employee Form 添加一个Button: Save。代码如下:
public String rootAMSave_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
service.saveEmployee();
return null;
}
(4)拖放root AM DC中的NestedAppModule1中的JobView1,选择Form。
(5)同样也为这个Job Form 添加两个Button: Create和Delete。代码如下:
public String nestedAMCreate_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
NestedAppModuleImpl nestedService = (NestedAppModuleImpl)service.getNestedAppModule1();
nestedService.createJob();
return null;
}
public String nestedAMDelete_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
NestedAppModuleImpl nestedService = (NestedAppModuleImpl)service.getNestedAppModule1();
nestedService.deleteJob();
return null;
}
(6)直接拖放Nested AM DC中的JobView1,选择Form。
(7)同样也为这个Job Form 添加两个Button: Create和Delete。代码如下:
public String topNestedAMCreate_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("NestedAppModuleDataControl");
NestedAppModuleImpl service = (NestedAppModuleImpl)am;
service.createJob();
return null;
}
public String topNestedAMDelete_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("NestedAppModuleDataControl");
NestedAppModuleImpl service = (NestedAppModuleImpl)am;
service.deleteJob();
return null;
}
5. 运行
为了说明问题,我测试了如下场景:
(1)修改Employee表单的某个属性,但并不点击Save按钮提交,而是点击Nested AM inside Root AM中的Job表单的Create按钮提交。
现象:被修改的Employee 表单的属性被成功提交入库。
解释:Employee VO属于Root AM,选择的Job VO属于Nested AM inside Root AM,它们使用同一个Transaction。
因此当修改前一个表单后,虽然提交的是另一个表单,前一个表单的数据也被提交了。
(2)修改Nested AM inside Root AM中的Job表单的某个属性,但并不点击Create/Delete按钮提交,而是点击Root AM中的Employee表单的Save按钮提交。
现象:被修改的Job 表单的属性被成功提交入库。
解释:同(1)。
(3)修改Employee表单 的某个属性,但并不点击Save按钮提交,而是点击 Nested AM outside Root AM中的Job表单的Create按钮提交。
现象:被修改的Employee 表单的属性并没有被写入数据库。
解释:Employee VO属于Root AM,选择的Job VO属于Nested AM outside Root AM,相当于是一个Root AM,二者是平行AM的关系,各自管理各自的Transaction。
当修改前一个表单后,而提交的是另一个表单,前一个表单的数据并没有被提交。
(4)修改Nested AM outside Root AM中的Job表单的某个属性,但并不点击Create/Delete按钮提交,而是点击Root AM中的Employee表单的Save按钮提交。
现象:被修改的Job 表单的属性并没有被写入数据库。
解释:同(3)。
6. 结论
(1)Nested AM与Root AM 使用的是同一个Transaction,都是Root AM中的Transaction,无论使用哪个AM提交,另一个AM中的VO也会被提交。
(2)多个Root AM之间的Transaction互不干涉,各自管理自己的。
(3)所以,要想避免提交本不想提交的表单,该表单所对应的VO的AM必须是Root AM。
7. 补充说明
以上提交方法都是使用getTransaction().commit(); 。
经过进一步测试,使用DataControl提供的Commit操作(拖放到页面上),实验结果和上述测试相同。
在实际应用中,为了达到逻辑重用的目的,会使用嵌套的AM。
在Root AM和Nested AM中都有各自的VO,在一个页面中,可能同时用到了不同AM的不同的VO,那么当一个AM提交时,另一个AM是否也会提交呢?
其实,这个问题的产生来自于一个客户的真实情况:
在一个页面中,有多个Tab页签,每个Tab页签中都一个表单和保存按钮。
用户可以选择修改Tab页签中的表单,于是就出现了这种情况:
用户修改了某个Tab页签中的表单,没有马上提交,接着修改另一个Tab页签中的表单,并点击这个Tab页签中的保存按钮,结果发现前一个页签中的修改也被成功提交了。
为了更加清楚阐述这个问题,我做了一个实验。
实验步骤主要如下:
1. 创建并定制化AppModule,包含JobVO和EmployeeVO。
增加3个方法,代码如下:
public void createJob() { JobsViewImpl jobVO = (JobsViewImpl)getJobsView1(); JobsViewRowImpl newJob = (JobsViewRowImpl)jobVO.createRow(); jobVO.insertRow(newJob); newJob.setJobId("Oracle"); newJob.setJobTitle("CEO"); newJob.setMinSalary(new Integer(10000)); newJob.setMaxSalary(new Integer(50000)); getTransaction().commit(); } public void deleteJob() { JobsViewImpl jobVO = (JobsViewImpl)getJobsView1(); JobsViewRowImpl currentJob = (JobsViewRowImpl)jobVO.getCurrentRow(); jobVO.removeCurrentRow(); getTransaction().commit(); } public void saveEmployee() { getTransaction().commit(); }
2. 创建并定制化NestedAppModule,包含JobVO。
(1)创建
(2)定制化
增加2个方法,代码和AppModule前2个方法相同,略。
3. 把NestedAppModule加入到AppModule中。
(1)
(2)完成后的Data Control
4. 创建页面,内容如下:
(1)拖放root AM DC中的JobView1和EmployeeView1,都选择Form。
(2)为Job Form 添加两个Button: Create和Delete。代码如下:
public String rootAMCreate_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
service.createJob();
return null;
}
public String rootAMDelete_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
service.deleteJob();
return null;
}
(3)为Employee Form 添加一个Button: Save。代码如下:
public String rootAMSave_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
service.saveEmployee();
return null;
}
(4)拖放root AM DC中的NestedAppModule1中的JobView1,选择Form。
(5)同样也为这个Job Form 添加两个Button: Create和Delete。代码如下:
public String nestedAMCreate_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
NestedAppModuleImpl nestedService = (NestedAppModuleImpl)service.getNestedAppModule1();
nestedService.createJob();
return null;
}
public String nestedAMDelete_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("AppModuleDataControl");
AppModuleImpl service = (AppModuleImpl)am;
NestedAppModuleImpl nestedService = (NestedAppModuleImpl)service.getNestedAppModule1();
nestedService.deleteJob();
return null;
}
(6)直接拖放Nested AM DC中的JobView1,选择Form。
(7)同样也为这个Job Form 添加两个Button: Create和Delete。代码如下:
public String topNestedAMCreate_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("NestedAppModuleDataControl");
NestedAppModuleImpl service = (NestedAppModuleImpl)am;
service.createJob();
return null;
}
public String topNestedAMDelete_action() {
ApplicationModule am = ADFUtils.getApplicationModuleForDataControl("NestedAppModuleDataControl");
NestedAppModuleImpl service = (NestedAppModuleImpl)am;
service.deleteJob();
return null;
}
5. 运行
为了说明问题,我测试了如下场景:
(1)修改Employee表单的某个属性,但并不点击Save按钮提交,而是点击Nested AM inside Root AM中的Job表单的Create按钮提交。
现象:被修改的Employee 表单的属性被成功提交入库。
解释:Employee VO属于Root AM,选择的Job VO属于Nested AM inside Root AM,它们使用同一个Transaction。
因此当修改前一个表单后,虽然提交的是另一个表单,前一个表单的数据也被提交了。
(2)修改Nested AM inside Root AM中的Job表单的某个属性,但并不点击Create/Delete按钮提交,而是点击Root AM中的Employee表单的Save按钮提交。
现象:被修改的Job 表单的属性被成功提交入库。
解释:同(1)。
(3)修改Employee表单 的某个属性,但并不点击Save按钮提交,而是点击 Nested AM outside Root AM中的Job表单的Create按钮提交。
现象:被修改的Employee 表单的属性并没有被写入数据库。
解释:Employee VO属于Root AM,选择的Job VO属于Nested AM outside Root AM,相当于是一个Root AM,二者是平行AM的关系,各自管理各自的Transaction。
当修改前一个表单后,而提交的是另一个表单,前一个表单的数据并没有被提交。
(4)修改Nested AM outside Root AM中的Job表单的某个属性,但并不点击Create/Delete按钮提交,而是点击Root AM中的Employee表单的Save按钮提交。
现象:被修改的Job 表单的属性并没有被写入数据库。
解释:同(3)。
6. 结论
(1)Nested AM与Root AM 使用的是同一个Transaction,都是Root AM中的Transaction,无论使用哪个AM提交,另一个AM中的VO也会被提交。
(2)多个Root AM之间的Transaction互不干涉,各自管理自己的。
(3)所以,要想避免提交本不想提交的表单,该表单所对应的VO的AM必须是Root AM。
7. 补充说明
以上提交方法都是使用getTransaction().commit(); 。
经过进一步测试,使用DataControl提供的Commit操作(拖放到页面上),实验结果和上述测试相同。
Project 下载:ADF_NestedAM_Transaction.7z
http://maping930883.blogspot.com/2012/06/adf152amnested-amroot-amtransaction.html
0 0
- AM使用指南之二:Nested AM与Root AM之间的Transaction关系
- AM使用指南之一:Transaction和DBTransaction的区别与联系
- am
- AM使用指南之五:在AM中执行SQL语句
- AM使用指南之六:使用Shared AM提高性能
- Makefile.am和Makefile.in以及Makefile之间的关系
- configure, Makefile.am, Makefile.in,Makefile之间的关系
- FM 与 AM的区别
- Makefile.am, Makefile.in 与 Makefile的关系
- Makefile.am, Makefile.in 与 Makefile的关系
- Makefile.am, Makefile.in 与 Makefile的关系
- AutoMake系列之二,Makefile.am文件的编写
- AM使用指南之三:如何在Managed Bean中获取AM实例?
- AM使用指南之四:把AM中的方法发布为WebService
- AM pool中的AM实例的生命周期
- AM pool中的AM实例的生命周期
- AM与PM
- AM使用指南:如何在Managed Bean中获取AM实例?
- Android PopupWindow 仿微信弹出效果
- Scala继承
- COFF 与PE文件
- Mathematically Hard (欧拉定理)
- flume-ng+Kafka+Storm+HDFS 实时系统搭建
- AM使用指南之二:Nested AM与Root AM之间的Transaction关系
- 黑马程序员,黑马论坛------(分享)Java 中的异常处理机制的简单原理和应用
- 菜鸟系列之C/C++经典试题(二)
- AM使用指南之三:如何在Managed Bean中获取AM实例?
- http://poj.org/problem?id=2251
- hdu 4967 Handling the Past 线段树 2014 Multi-University Training Contest 9-1008
- AM使用指南之四:把AM中的方法发布为WebService
- AM使用指南之五:在AM中执行SQL语句
- POJ1228-Grandpa's Estate(凸包)