i think is better to see the source code.
file:1.jsp
InitialContext ic = new InitialContext();
Object obj = initialcontext.lookup("ejb/ShoppingCart");
ShoppingCartHome sch = (ShoppingCartHome)
PortableRemoteObject.narrow(obj, abayi.ShoppingCartHome.class);
ShoppingCart sc=sch.create();
/**
*sc.begin() this method is include the jta "UserTransaction
*Object in internal" and this begin method will invoke the
*UserTransaction.begin this method
**/
sc.begin();
session.setAttribute("sc",sc);
response.sendRedirect("2.jsp");
file:2.jsp
ShoppingCart sc=(ShoppingCart)session.getAttribute("sc");
String data=request.getParameter("item");
if(data!=null)
sc.add(data);
%>
<form action=2.jsp>
<input type=text name=item>
<input type=submit>
</form>
<form action=3.jsp>
<input type=submit name="COMMAND" value="COMMIT">
</form>
<form action=3.jsp>
<input type=submit name="COMMAND" value="CANCEL">
</form>
<%

file:3.jsp
<%
ShoppingCart sc=(ShoppingCart)session.getAttribute("sc");
if(request.getParameter("COMMAND").equals("COMMIT"))
{
/**
*this commit method is include the jta commit method.
*
**/
sc.commit();
}
else
{
//this method is invoke the jta rollback method.
sc.rollback();
}
response.sendRedirect("index.html");
%>

==========================================================
my problem is will this code will get error .


i think is better to see the source code.
[b]file:1.jsp[/b]
InitialContext ic = new InitialContext();
Object obj = initialcontext.lookup("ejb/ShoppingCart");
ShoppingCartHome sch = (ShoppingCartHome)
PortableRemoteObject.narrow(obj, abayi.ShoppingCartHome.class);
ShoppingCart sc=sch.create();
/**
*sc.begin() this method is include the jta "UserTransaction
*Object in internal" and this begin method will invoke the
*UserTransaction.begin this method
**/

sc.begin();
session.setAttribute(
"sc",sc);
response.sendRedirect(
"2.jsp");
[b]file:2.jsp[/b]
ShoppingCart sc=(ShoppingCart)session.getAttribute(
"sc");
String data=request.getParameter(
"item");
if(data!=null)
sc.add(data);
%>
<form action=2.jsp>
<input type=text name=item>
<input type=submit>
</form>
<form action=3.jsp>
<input type=submit name=
"COMMAND" value="COMMIT">
</form>
<form action=3.jsp>
<input type=submit name=
"COMMAND" value="CANCEL">
</form>
<%

[b]file:3.jsp[/b]
<%
ShoppingCart sc=(ShoppingCart)session.getAttribute(
"sc");
if(request.getParameter(
"COMMAND").equals("COMMIT"))
{
/**
*this commit method is include the jta commit method.
*
**/

sc.commit();
}
else
{
//this method is invoke the jta rollback method.
sc.rollback();
}
response.sendRedirect(
"index.html");
%>

==========================================================
my problem is will this code will get error .

Please move all of the "Db" operations, e.g. start transaction, sql operation/invoking entity Bean, ... into one method. E.g. ShoppingCart.writeBack()

In 1.jsp: don't start transaction
In 2.jsp: the ShoppingCart.add() should not do any sql operation or invoke entity Bean.
In 3.jsp: call ShoppingCart.writeBack() which updates the database or invokes another entityBean to persist data.

i know want do it like your solution. but why we cant do it like that.

我认为这种在Jsp中调用如此多业务逻辑,甚至操作数据库的做法是错误的。
请重整Refactorying,将所有的业务逻辑放入JavaBean中。

为什么说是错误的?
因为你现在出了问题,我也无法帮你忙,我想没几个人能够帮你忙,真的。

程序编写不规范造成的问题是系统不稳定最大的原因。


但是请问,你的solution比别人的能完成别人的solution不能完成的功能吗?

你的solution又比别人的容易出错多吧?

你的solution的简化部分到了项目当中又能节省多少呢,还是不是关键呢?

所以你的solution是非常差劲的,因为当中有那么多的不可以控制因素然而得到的额外的好处几乎为0!

所以,这个不是个好的solution.

to Bangq:
那你认为以下的做法可行吗?这只是中间元件的作法。

以下是我全部的做法。jsp this layer ,i still read the sturts framework.
jsp : just 操作业务逻辑, like ejb.
jb : use to do and finish the 业务逻辑,and operate
the DAO to control the database .
dao : this object is really 操作数据库.
这样算是程序编写不规范吗?我是新手,正在建立正切的观念。请多多指教。

可能那个example 让你误解。不好意思。我也想之道你如何在jsp
this layer 来操作业务逻辑?因一些逻辑要跨几个interface才可以完成的你又如何完成。是不是将他暂存在memory,finally just invoke the ejb and pass the data or information to the business logic bean.
因为这样有点麻烦,所以才想将这类逻辑操作让ejb 或jb来完成。但是想到ejb的jta是用Thread绑定DB connection的方式来处里。但是ejb save into http session ,在web container将不会让Thread 绑定 session内的ejb or jb 呀!因此才会问这个问题。invoke ejb ,jta in tomcat server will get error?.如有人知道他们如何解决,请告述我。当是研究吧。

abayi,是的,跨页面的信息一定要放在什么地方.如果不是JTA里面,就是在内存里面(不管是在session里面还是其他什么地方,比如queryString)

不做点东西,比hello World要复杂的东西,自己空对空,会浪费好多的的时间去空想一些个不太重要的东西.比如现在的这个问题.

多想想你原来的solution在测试方面和不稳定性方面的影响吧,这点成本就足够你考虑要不要使用它了.

在项目里面原有比省掉几个mem object(实际是Model Objects)更重要的东西,比如稳定性,比如跨数据库性,可测试性,等等.

算算帐吗?划算吗?

怎么也不可能选泽你的那个方法.这个就是开发web的麻烦,开发GUI的东西,你的方法也许会被我选择的,至少可能性会大一点.

to liloboy :
is like that,can share your solution to let me do the research???
thanks you.

and also share how you test your web application? i not any good solution in domain?

to abayi

我感觉你的问题很有普遍性,你对EJB不是很了解,就盲目使用EJB,进入了EJB使用误区,亏得你在这里提出问题,否则你这个项目失败后,你肯定对EJB恨得咬牙切齿,然后,到处抱怨EJB的问题,很多人都走过了你这条路。


1. 如果使用EJB,那么尽量使用EJB的CMT,也就是容器事务机制,非常简单,不会出现不稳定或bug,当然,前提是你对EJB的容器事务机制熟悉,特别是required、new等几个设置必须详细了解。

2. 如果使用了EJB的CMT,就没有理由使用JTA,特别是SFSB+JTA,非常耗费性能,如果需要跨EJB服务器,建议在Web和EJB服务器之间加一个SLSB Facade,建议你学习相关EJB设计模式。

3. 如果一定要用JTA,就尽量不用EJB,这时框架可以推荐使用Spring,这是一个反EJB人士倡导的开源框架,他在为他的设计理想奋斗,目前来看,Spring能够在轻量、单机情况下替代SLSB,当然你必须学会忍受开源API的“出尔反尔”。

如果你不认同上述建议,那么建议学习一下SUN的J2EE核心模式。


>可能那个example 让你误解。不好意思。我也想之道你如何在jsp
>this layer 来操作业务逻辑?因一些逻辑要跨几个interface才可以完成>的你又如何完成。是不是将他暂存在memory,finally just invoke the >ejb and pass the data or information to the business logic bean.

依据我上贴设计思维,你这个答案有两个:
1.如果使用EJB,那么使用SFSB来实现跨几个interface才完成的,因为SFSB是保存在内存中的,这时,事务机制使用CMT。

2.如果不用EJB,而是使用普通JavaBeans,Spring最新版本提供了事务机制功能,如果你觉得功能不够,可以在你的jb中直接使用JTA。


我想你应该明白了,如果你非得好奇地想找出第三个途径,那么要么出现你提问题的errors,可能永远无法解决;要么你成为这方面的高手中之高手了。

补充,上贴第2个方案中,你可以使用HttpSession作为临时对象暂存处,对内存临时对象处理,最后一次性写入数据库,自己要处理好JTA的roll back关系。不要有盲点。

看了半天不知道我理解了没有。你的问题实际是这样的,jta实际上维护了stateful session bean和transaction之间的连接,所以有状态会话bean是可以在不同的操作间维护一个事务的,你的代码也证明了这一点。 而你所不明白的是,不同的jsp拿到的为什么是同一个远程session bean的句柄,其实是因为你对session变量的不理解,在一次会话中session变量的只有一个,你可以print出来session.getId()看一下,再关掉ie重新访问一次试一下,这也是session被翻译成会话的原因吧。