⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 19.html

📁 写给JSP初级程序员的书
💻 HTML
📖 第 1 页 / 共 4 页
字号:
      bean,bean的类,接口和串行化的部署描述符放在一个jar文件中。这个jar文件必须有一个manifest文件的入口以声明一个enterprise 
      bean的部署描述符。<BR>Name:AccountDD.ser<BR>Enterprise-Bean:true<BR><BR>  在manifest中作为enterprise 
      bean列出的是部署描述符,而不是bean类。部署描述符除了定义enterprise 
      bean,还提供jar文件中所有文件的完整描述。开发者不必关心EJB 
      jar文件的创建。厂商应该提供一个工具来帮助开发者创建部署描述符,然后把所有必须的文件打包进一个jar文件中。<BR><BR>***********</SPAN></P>
      <P><SPAN class=txt><B><FONT color=#ff0033>3.事务</FONT></B><BR><BR>CORBA 
      OTS<BR><BR>  EJB的事务模型与OTS类似。事实上,CORBA兼容的EJB服务器必须提供一个OTS兼容的事务服务。理解OTS如何工作有助于理解EJB中事务的工作方式。<BR><BR><B>定义事务</B><BR><BR>   
      一个事务正式地定义了一个原子工作单位。一个事务中可以包含多个操作,当事务终止时,所有执行的操作或者完全执行或者完全废弃。这称为提交和回滚。<BR><BR>  在数据库应用中广泛地使用事务。好的数据库产品对事务提供很强的支持。一个事务中访问的记录在整个事务持续期间保持锁定状态。基于数据库产品在事务开始时可以选定不同的锁定状态。选定的锁定级别应在其它的事务中优化操作的并发访问时保证数据的完整性。网络上的事务可能是分布式的,例如客户端可能在单个事务中访问两个不同的数据库。为了支持分布式事务,大多数事务管理器(包括数据库)支持两段提交。在两段提交协议中,事务管理器在准备提交事务前首先询问所有的事务参与者的工作是否完成。这是协议的第一阶段。一旦每个参与者同意提交,第二阶段才会开始。事务管理器发送独立的提交操作的命令。<BR><BR><B>OTS中的关键部件<BR></B><BR>  为了更好地理解OTS如何工作,我们需要先看看其关键部件。以下的部件可以直接地映射到EJB,而理解这些部件如何在OTS中工作能使我们更好地理解EJB中的事务。<BR>Control<BR>terminator<BR>Coordinator<BR>Resource<BR>Synchronization<BR><BR>  下图示出了这些对象中定义的重要方法,以及在事务体系中这些对象的作用。<BR><BR><IMG 
      height=335 src="ejb_img3.jpg" tppabs="http://www.chinajavaworld.com/doc/ejb/images/ejb_img3.jpg" 
      width=501><BR><BR>  虚线框内是一个事务。事务中所有的对象都参与了这个事务,提交和回滚对所有的Resource对象都适用。 
      Control对象代表一个事务。从该对象我们可以得到Coordinator和Terminator 
      。EJB开发者不会看到Control对象,容器代表bean用Control对象来管理事务。<BR><BR>  当一个bean方法返回且该方法在部署描述符中声明在方法返回前需提交该事务时,容器也用Terminator来提交或回滚事务。提交或回滚事务时,所有事务中的对象都会相应的提交或回滚。<BR><BR>  Resource是包含事务状态的对象。例如,它可能是一个数据库连接。在这个对象上调用commit()会更新数据库。一个rollback()调用会恢复该事务开始时通过这个连接对数据作的任何改变。完成提交或回滚后,数据库中相应的记录就会解锁。应用的锁级别会在部署描述符中指定。这个对象的完全的方法集会显示这些对象实现了两段提交协议,使得每一个对象都有权决定整个事务是提交还是回滚。当一个事务完成时,不论是提交还是回滚,都要通知Synchronization对象。与Resource不同,它并不参与两段提交协议,所以无权表决一个事务应该提交还是回滚。在事务中它扮演一个被动的角色。 
      Coordinator是使这一切工作起作用的对象。Resource和Synchronization通过该对象注册到事务中。Bean不直接访问这个对象。 
      Transaction-aware objects that are intended for use with EJB will 
      transparently obtain a reference to the current transaction"s Coordinator 
      to register 
      itself.<BR><BR><B>事务和可恢复的对象<BR></B><BR>  在OTS中事务和可恢复的对象不同。这个区别与EJB有关。在CORBAservice? 
      OTS规范中详细地定义了这些类型,简单地说,可恢复对象有commit()和rollback()方法,允许事务直接地操纵它自己的状态和行为。一个事务对象没有这些方法,不能被事务影响。然而,事务对象有与其关联的事务,以使分配的可恢复对象(或Resources)与事务对象的当前事务相关联。一个enterprise 
      bean是一个事务对象的好例子。容器代表bean维护事务。任何bean分配的可恢复对象在容器的帮助下透明地放置在事务中。Bean没有commit()或rollback()方法,因此事务不能直接操纵bean.让bean作为一个可恢复的Resource并没有什么意义,因为这使得bean开发者必须为每个bean添加额外的代码,而enterprise 
      bean几乎没有内在状态应该影响一个外部的事务。让enterprise 
      bean作为可恢复对象的管理者,让可恢复对象完成这个工作会更好。<BR><BR>  注意bean在容器试图提交或回滚之前可以有权表决回滚一个事务。在EJBContext中Bean可以用Coordinator中的rollback_only()方法作为setRollBackOnly()给事务设置标志,以使事务终止时间到达时请求回滚。还可以通过SessionSynchronization接口通知一个bean有关一个事务的结果。<BR><BR><B>在部署描述符中指定事务控制<BR></B><BR>  bean的部署描述符包含一个ControlDescriptor对象的数组。每个ControlDescriptor描述了与方法关联的事务控制。 
      Bean开发者指定bean方法中的事务控制。部署者在对方法的事务相关行为没有细致了解的情况下一般不应改变这些值。如下的六个事务控制是在ControlDescriptor类定义的整形常量。除了该类的方法,没有其它的APIs能访问它们。Bean本身不访问事务控制。 
      Bean本身的方法不能访问其事务属性。容器读取这些控制值来维护bean的相应的事务行为。<BR><BR><BR>?TX_NOT_SUPPORTED<BR>?TX_SUPPORTS<BR>?TX_REQUIRED<BR>?TX_REQUIRES_NEW<BR>?TX_MANDATORY<BR>?TX_BEAN+NANAGED<BR>  你可以通过厂商提供的创建部署描述符的工具来为bean设置合适的ControlDescriptor.<BR>TX_NOT_SUPPORTED<BR>  该方法不应运行在事务上下文中。如果在一个事务中执行线程,那么这个事务将挂起直到线程从方法中返回。<BR>TX_SUPPORTS<BR>  该方法不需要事务,运行该方法时线程可能有一个活动的事务。<BR>TX_REQUIRED<BR>  该方法必须运行在事务中。如果线程已经有一个事务,则这个线程允许进入此方法。如果线程没有事务,则容器代表线程启动一个允许线程进入的事务,当线程返回是终止事务。一般应提交事务。如果现成调用setRollbackOnly()方法,则容器相应地执行一个回滚。<BR>TX-REQUIRED_NEW<BR>  不论线程是否有一个事务,容器都会在方法调用期间创建一个事务。当线程返回时,容器提交或回滚这个事务。如果线程有一个进行中的事务,则新事务会挂起直到线程返回或方法的事务终止。<BR>TX_MANDATORY<BR>  当调用这个方法时线程必须已经在一个事务中。如果线程没有事务,则容器会抛出一个例外。<BR>TX_BEAN_MANAGED<BR>  这个与上述几个不同。这种方法表明容器不应在事务管理中起作用。<BR><BR><B>JTS-Java事务服务</B><BR><BR>  实际上JTS不是一个事务服务--只是底层服务提供者的一层接口。JTS非常简单,由一个接口和几个例外组成。从例外列表很容易能看出它类似OTS,虽然它也可以作为其它服务的接口。对于声明事务控制方式为自管理的bean,可以通过这个接口访问事务服务。厂商也可以用它来提供对客户端划分事务的支持。<BR><BR><BR>如下是UserTransaction接口的定义:<BR><BR>public 
      interface javax.jts.UserTransaction {<BR>public void begin() throws 
      IllegalStateException;<BR>public void commit() 
      throws<BR>TransactionRolledBackException,<BR>HeuristicMixedException,<BR>HeuristicRollbackException,<BR>SecurityException,<BR>IllegalStateException;<BR>Public 
      void rollback() 
      throws<BR>SecurityException,<BR>IllegalStateException;<BR>Public void 
      setRollbackOnly() throws<BR>IllegalStateException;<BR>public void 
      setTransactionTimeout(int seconds);<BR>public int 
      getStatus();<BR>//STATUS_ACTIVE,STATUS_COMMITTING,<BR>//STATUS_COMMITTED,STATUS_MARKED_ROLLBACK<BR>//STATUS_NO_TRANSACTION,STATUS_PREPARED<BR>//STATUS_PREPARING,STATUS_ROLLEDBACK<BR>//STATUS_ROLLING_BACK,STATUS_UNKNOWN<BR>}<BR>*******************</SPAN></P>
      <P><SPAN class=txt><B>自管理的事务</B><BR><BR>   
      如果声明一个bean的事务控制为TX_BEAN_MANAGED,则这个bean可以访问事务服务。当事务控制应用于单个的方法时这个控制只能应用于整个的bean. 
      bean访问事务服务的能力不能只对某个方法起作用。因此一个方法声明事务控制为TX_BEAN_MANAGED,而另一个方法声明为其它不同的事务控制是错误的。厂商的安装工具应该能检测到并报告这个错误。Bean分别通过初始化时setSessionContext()或setEntityContext()方法的参数 
      SessionContext或EntityContext来访问事务服务。这些接口都是EJBContext的子类。<BR><BR>  EJBContext的定义如下:<BR><BR>Public 
      interface javax.ejb.EJBContext {<BR>public Identity 
      getCallerIdentity();<BR>public boolean isCallerInRole(Identity 
      other);<BR>public EJBHome getEJBHome();<BR>public Properties 
      getEnvironment();<BR>public UserTransaction getUserTransaction() 
      throwsIllegalStateException;<BR>public boolean 
      getRollbackOnly();<BR>public void set 
      RollbackOnly();<BR>}<BR><BR><BR>  一旦bean获得了一个UserTransaction的引用,就可以用这个引用管理自己的事务。有状态的会话bean的方法可以创建一个事务,而且不用终止事务就可以返回。如果还有线程调用bean的方法,容器检测是否有bean创建的活动的事务,如果被调用的事务是同一个事务,容器会允许该线程重新进入这个bean.如果bean在事务中且执行不同事务上下文的线程试图进入bean,容器会阻塞这个线程直到bean的事务终止。如果线程试图进 
      入事务时bean不在事务中,线程会执行一个自己的事务,容器会挂起线程当前的事务以允许线程进入。一旦线程离开方法就会恢复线程以前的事务,容器不会终止任何方法创建的事务。<BR><BR>   
      对于无状态会话bean和实体bean,当事务活动时bean的方法不允许返回。容器会为此抛出一个例外。<BR><BR>Leaving a 
      tranaction active across method calls is stateful,and is not allowed for 
      stateless session beans.Fro similar reasons,entity beans are also not 
      allowed to maintain an open transaction state across method calls when the 
      bean has declared the TX_BEAN_MANAGED transaction 
      control.<BR><BR><BR><B>会话同步接口<BR><BR>  </B>有状态和无状态的会话bean都可以访问数据库,并且参与一个事务。为了让bean在事务中执行它的任务,bean开发者可以实现在bean中实现 
      javax.ejb.SessionSynchronization接口。容器能自动检测这个接口,容器会使用这个接口中的方法以使bean得到事务的状态信息。实体bean不支持这个接口。因为实体bean 
      are implicitly transaction aware,所以容器使用不同的方法控制一个事务中的实体 
      bean.<BR><BR>  SessionSynchronization接口定义如下:<BR><BR>public interface 
      javax.ejb.SessionSynchronization {<BR>public void afterBegin() throws 
      RemoteException;<BR>public void beforeCompletion() throws 
      RemoteException;<BR>public void afterCompletion(boolean yn) throws 
      RemoteException;<BR>}<BR><BR>  实际上一个事务不属于一个特殊的bean的实例。一个客户端或容器中执行的线程创建一个事务,在执行bean中的代码时执行该事务。如果一个有事务上下文的线程将要进入一个会话bean,容器首先调用它的afterBegin()方法。Bean可以记录所有的商业方法运行在事务中,随后执行事务操作。如果一个操作的内部标志显示这个线程在事务外运行,则会拒绝执行事务操作的请求。直到调用afterCompletion()方法,bean会继续认为商业方法的调用都在事务中执行。Bean将推断性地清除内部标志,以表示随后到来的事务请求将被拒绝。<BR><BR>  如果一个事务上下文的线程试图进入一个已经是另一个事务的一部分的Bean时, 
      .Container将封锁入口,直到前一个事务提交或回滚,并且afterCompletion()方法被调用,此时,允许Bean 
      恢复它的状态。Container负责提供这些行为。当Container发现它将要提交一个事务时,将在这个事务的所有的session 
      Bean上调用beforeCompletion()方法。这就给Bean足够的机会来结束事务的操作,如在提交前将数据写入数据库。反之,当Container 
      发现,将要回滚一个事务撕,BeforeCompletion()方法将不会被调用,因为将一个将被回滚的事务所产生的数据写入数据库是没有意义 
      的。<BR><BR>  AfterCompletion()是在一个事务即将提交或回滚时被调用,来通知Bean事务操作的最终结果。Bean可以用这个信息来修正自己的内部状态,但它不能用这个信息来维持任何它将要保存的事务。尽管session 
      Bean可以创建,提交和回滚它自己的事务,但通常不推荐这样做。<BR><BR>  SessionSynchronization接口不提供整合外部和内部事务的能力。如果一个session 
      bean实现了这个接口,则意味着它在方法调用之间要保持事务的状态。特别地,这也暗示在afterBegin()和afterCompletion()调用之间bean是处于一个事务中。这样,如果一个bean实现了SessionSynchronization接口并且在装配符中声明是无状态的就是一个错误。厂商提供的安装工具应该可以捕捉到并报告这个错误。无状态的session 
      bean可以加入一个事务,但它们不能实现这个接口。事务可以是TX_BEAN_MANAGED,或者container可以在方法入口和从方法的返回上来开始和提交这个事务。Container不可允许在一个现存的事务中有一个线程进入方法,因为无状态的Bean的方法将无法知道正在运行的线程是否正在一个事务中。<BR><BR>  解决这个问题的一个方法是使container挂起现存的事务,强迫方法总是认为线程没有在一个事务性的上下文中运行。有状态的Bran可以不实现这个接口而介入事务。但是,装配符必须要认真地配置以使得商务方法总能在正确的事务状态中运行。Bean自己没有通过这个接口来获得自己的事务的状态的权利。<BR><BR><B>加入事务<BR><BR></B>  EJBContext接口在前面的一节中已经介绍了。其中有两个方法:<BR><BR>public 
      boolean getRollbackOnly();<BR>public void 
      setRoolbackOnly();<BR><BR>  这些方法可以有任何bean来使用,而不仅仅是那些声明了其事务控制为bean-managed的bean。事实上,那些处理自己的事务的bean将不会用到这些方法,因为这些方法不是用来和外界的事务管理器进行交流事务状态的。<BR><BR>  当一个bean调用了setRollBackOnly()方法时,它是在向事务管理器询问何时结束将要回滚的当前事务。它将给它所参与的事务的结果一个选票。这些方法还存在于UserTransaction接口中,但由于大多数的bean都不访问这个接口,这些方法必须直接地在EJBContext中提供给bean。注意这个方法并不引发回滚操作,它只是简单地设置标志,表示事务在结束时应该回滚。不象JavaBan属性设置方法,这个方法不以boolean值作为参数。这个方法是特意设计成这样,以使得一个bean不能够改变另一个bean的回滚请求。一个bean也许希望使用getRoolBackOnly()方法,来检查当前的事务的状态。如果另一个bean已经标志这个事务为rollback,则正在调用的bean可以推测到并决定不能执行那些在、强制性达到操作,如数据库更新,而这些操作很有可能在事务结束时被反转过来。<BR><BR><B>客户划分的事务</B><BR><BR>  尽管一个JEB厂商所必须的,大服务器厂商也许决定提供一个类,使得用户可以直接访问事务管理器。当需要在同一个上下文中在两个不同的服务器上调用bean时,用户也许会希望这样做。当然,每个bean的装配符可以允许这样的行为。用户可以创建一个事务,然后在两个不同server上的两个不同的bean上调用商务方法,而将事务的上下文也作为调用的一部分进行传递。一旦调用结束,用户将推测地结束事务。有container厂商产生的stub和skeleton将支持事务上下文的隐式传递。<BR><BR>  这里是一个可能的例子:<BR><BR>Current 
      current = new 
      Current();<BR>Current.setServiceProvider(txMgrURL);<BR>Current.create();<BR>Current.begin();<BR>Current.doSomeWork();<BR>RemRef1.doSomeWork();<BR>RemRef2.doMoreWork();<BR>Current.commit();<BR><BR><B>数据库操作的事务管理</B><BR><BR>  bean当然希望使用JDBC来建立到数据库的连接,并在其上进行操作。但是,为了符合EJB这种container管理事务的模式,连接不能使用自动提交特性,并且不应该在连接上试图提交或回滚。<BR><BR>  Container的角色是决定在这个事务中执行的所有行为应该提交还是回滚。这里提这样一个问题很好:container如何看到并管理由bean方法内部创建的数据库连接。尽管在规范中没有明确地提到,EJB将只能使用JDBC驱动,而JDBC也正是用来和EJB配合使用的。在数据库连接的创建时,驱动程序透明地将连接注册到正在执行的线程的当前事务中。之后当container决定结束事务时,数据库连接将自动地结束它。用OTS的术语说,数据库连接是不可恢复的资源,有事务服务在container的协助下,隐式地管理。尽管可以在这种情况下使用非事务感知的JDBC 
      Driver,但开发者必须清楚任何在数据库连接上所做的操作都不属于bean的事务,开发者还必须确保在从方法返回之前结束数据库连接事务。试图使用SessionSynchronization接口来合并数据库连接事务和bean本身的事务是不可靠的,是不应该作的。<BR><BR><B>分布事务的支持<BR></B><BR>  一个分布事务在下面的情况下是需要的:<BR>  . 
      一个用户使用用户划分的在多个server上的多个bean中创建和调用方法的事务。<BR>  . 
      一个在其他的server上调用其他EJB的方法的bean的方法。<BR><BR>   
      对于这些工作厂商必须为EJBObject生成stub和skeleton来隐式地获得当前事务的上下文,同时将其通过方法调用传到远程bean。当将商务方法调用委派给bean时,远程bean的EJBObject的skeleton必须请求这个事务的上下文。 </tr>
    </td>
  </tr>
</div>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -