当前位置: 首页 > news >正文

商城网站建设流程图网页设计与制作教程这本书

商城网站建设流程图,网页设计与制作教程这本书,北京自考网址,如何搭建一个视频网站ejb能调用另一个ejb吗在之前的文章#xff08; 此处和此处 #xff09;中#xff0c;我展示了当服务器负载沉重时#xff0c;创建非阻塞异步应用程序可以提高性能。 EJB 3.1引入了Asynchronous批注#xff0c;用于指定方法将在将来的某个时间返回其结果。 Javadocs声明必须… ejb能调用另一个ejb吗 在之前的文章 此处和此处 中我展示了当服务器负载沉重时创建非阻塞异步应用程序可以提高性能。 EJB 3.1引入了Asynchronous批注用于指定方法将在将来的某个时间返回其结果。 Javadocs声明必须返回void或Future 。 下面的清单显示了使用此注释的服务示例 Service2.java Stateless public class Service2 {Asynchronouspublic FutureString foo(String s) {// simulate some long running processThread.sleep(5000);s brService2: threadId Thread.currentThread().getId();return new AsyncResultString(s);} } 注释在第4行上。该方法返回String类型的Future 并在第10行上通过将输出包装在AsyncResult 。 在客户端代码调用EJB方法时容器拦截了该调用并创建了一个任务它将在另一个线程上运行以便它可以立即返回Future 。 当容器然后使用其他线程运行任务时它将调用EJB的方法并使用AsyncResult来完成给定调用者的Future 。 即使看起来与Internet上所有示例中的代码完全一样此代码也存在一些问题。 例如 Future类仅包含用于获取Future结果的阻塞方法而不包含用于在回调完成时注册回调的任何方法。 这将导致如下所示的代码当容器处于加载状态时这是很糟糕的 客户端程序 //type 1 FutureString f service.foo(s); String s f.get(); //blocks the thread, but at least others can run //... do something useful with the string...//type 2 FutureString f service.foo(s); while(!f.isDone()){try {Thread.sleep(100);} catch (InterruptedException e) {...} } String s f.get(); //... do something useful with the string... 这种代码是不好的因为它导致线程阻塞这意味着它们在这段时间内无法做任何有用的事情。 当其他线程可以运行时需要进行上下文切换这会浪费时间和精力有关成本或我以前的文章的结果请参见这篇好文章。 像这样的代码会使已经处于负载状态的服务器承受更大的负载并停止运行。 那么是否有可能使容器异步执行方法而编写不需要阻塞线程的客户端呢 它是。 以下清单显示了一个servlet。 AsyncServlet2.java WebServlet(urlPatterns { /AsyncServlet2 }, asyncSupported true) public class AsyncServlet2 extends HttpServlet {EJB private Service3 service;protected void doGet(HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {final PrintWriter pw response.getWriter();pw.write(htmlbodyStarted publishing with thread Thread.currentThread().getId() br);response.flushBuffer(); // send back to the browser NOWCompletableFutureString cf new CompletableFuture();service.foo(cf);// since we need to keep the response open, we need to start an async contextfinal AsyncContext ctx request.startAsync(request, response);cf.whenCompleteAsync((s, t)-{try {if(t!null) throw t;pw.write(written in the future using thread Thread.currentThread().getId() ... service response is:);pw.write(s);pw.write(/body/html);response.flushBuffer();ctx.complete(); // all done, free resources} catch (Throwable t2) { ... 第1行声明Servlet支持异步运行-不要忘记这一点 第8-10行开始将数据写入响应但是有趣的是第13行中的调用异步服务方法的行。 我们没有将Future用作返回类型而是向其传递了CompletableFuture 它用于将结果返回给我们。 怎么样 第16行会启动异步servlet上下文因此我们仍然可以在doGet方法返回后写入响应。 从第17行开始然后有效地在CompletableFuture上注册了一个回调一旦CompletableFuture完成并返回结果该回调将被调用。 这里没有阻塞代码–没有线程被阻塞没有线程被轮询等待结果 在负载下服务器中的线程数可以保持最少从而确保服务器可以高效运行因为需要较少的上下文切换。 服务实现如下所示 Service3.java Stateless public class Service3 {Asynchronouspublic void foo(CompletableFutureString cf) {// simulate some long running processThread.sleep(5000);cf.complete(bar);} } 第7行确实很丑陋因为它会阻塞但假装这是代码调用使用大多数Web服务客户端和JDBC驱动程序会阻塞的API调用在Internet或较慢的数据库中远程部署的Web服务的代码。 或者使用异步驱动程序 当结果可用时完成第9行所示的将来。然后向CompletableFuture发出信号可以调用在先前清单中注册的回调。 这不只是使用简单的回调吗 这肯定是相似的下面的两个清单显示了使用自定义回调接口的解决方案。 AsyncServlet3.java WebServlet(urlPatterns { /AsyncServlet3 }, asyncSupported true) public class AsyncServlet3 extends HttpServlet {EJB private Service4 service;protected void doGet(HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { ...final AsyncContext ctx request.startAsync(request, response);service.foo(s - { ...pw.write(/body/html);response.flushBuffer();ctx.complete(); // all done, free resources ... Service4.java Stateless public class Service4 {Asynchronouspublic void foo(CallbackString c) {// simulate some long running processThread.sleep(5000);c.apply(bar);}public static interface CallbackT {void apply(T t);} } 同样在客户端中绝对没有任何阻塞。 但是由于以下原因使用CompletableFuture的AsyncServlet2和Service3类的早期示例更好一些 CompletableFuture的API允许出现异常/失败 CompletableFuture类提供用于异步执行回调和相关任务的方法即在fork-join池中以便整个系统使用尽可能少的线程运行从而可以更有效地处理并发性 可将CompletableFuture与其他对象结合使用以便您可以注册一个回调仅在多个CompletableFuture完成时才能调用该回调 回调不会立即被调用而是池中有限数量的线程按它们应运行的顺序为CompletableFuture的执行提供服务。 在第一个清单之后我提到异步EJB方法的实现存在一些问题。 除了阻塞客户端之外另一个问题是根据EJB 3.1 Spec的 4.5.3章客户端事务上下文不会通过异步方法调用传播。 如果您想使用Asynchronous批注创建两个可以并行运行并在单个事务中更新数据库的方法那么它将不起作用。 这在某种程度上限制了Asynchronous注释的使用。 使用CompletableFuture 您可能会认为可以在同一个事务上下文中并行运行多个任务方法是先在EJB中启动一个事务然后创建多个可运行对象并使用runAsync方法运行它们该方法在执行中运行它们池然后注册一个回调以使用allOf方法完成所有操作后allOf 。 但是您可能会因为多种原因而失败 如果您使用容器管理的事务那么一旦导致事务开始的EJB方法将控制权返回给容器事务将被提交-如果那时您的期货还没有完成您将不得不阻止运行EJB方法的线程这样它就等待并行执行的结果而阻塞正是我们要避免的 如果运行任务的单个执行池中的所有线程都被阻塞等待它们的数据库调用应答那么您将有可能创建性能不佳的解决方案–在这种情况下您可以尝试使用非阻塞的异步驱动程序 但不能每个数据库都有这样的驱动程序 一旦任务在不同的线程例如执行池中的线程上运行线程本地存储TLS就不再可用因为正在运行的线程与将工作提交到执行池并进行设置的线程不同在提交工作之前将值存入TLS 诸如EntityManager 类的资源不是线程安全的 。 这意味着你无法通过EntityManager成提交给池的任务而每个任务需要得到它自己的保持EntityManager实例而是创建EntityManager取决于TLS见下文。 让我们用以下代码更详细地考虑TLS该代码显示了一种异步服务方法该服务方法试图做几件事以测试允许的操作。 Service5.java Stateless public class Service5 {Resource ManagedExecutorService mes;Resource EJBContext ctx;PersistenceContext(nameasdf) EntityManager em;Asynchronouspublic void foo(CompletableFutureString cf, final PrintWriter pw) {//pw.write(brinside the service we can rollback, i.e. we have access to the transaction);//ctx.setRollbackOnly();//in EJB we can use EMKeyValuePair kvp new KeyValuePair(asdf);em.persist(kvp);FutureString f mes.submit(new CallableString() {Overridepublic String call() throws Exception {try{ctx.setRollbackOnly();pw.write(br/inside executor service, we can rollback the transaction);}catch(Exception e){pw.write(br/inside executor service, we CANNOT rollback the transaction: e.getMessage());}try{//in task inside executor service we CANNOT use EMKeyValuePair kvp new KeyValuePair(asdf);em.persist(kvp);pw.write(...inside executor service, we can use the EM);}catch(TransactionRequiredException e){pw.write(...inside executor service, we CANNOT use the EM: e.getMessage());} ... 第12行没有问题您可以回滚在容器调用EJB方法时在第9行自动启动的事务。 但是该事务将不是可能由调用第9行的代码启动的全局事务。第16行也没有问题您可以使用EntityManager写入由第9行开始的事务内部的数据库。显示了在不同线程上运行代码的另一种方式即使用Java EE 7中引入的ManagedExecutorService 。但是这在任何时候都依赖TLS时也会失败例如第22行和第31行会导致异常因为在第9行启动的事务无法定位因为使用TLS来定位并且第21-35行中的代码使用与第19行之前的代码不同的线程运行。 下一个清单显示第11-14行在CompletableFuture上注册的完成回调也与第4-10行运行在不同的线程中因为在第6行的回调之外启动提交事务的调用将在第6行失败再次参考图13因为第13行的调用在TLS中搜索当前事务并且因为运行第13行的线程与运行第6行的线程不同所以找不到事务。 实际上下面的清单实际上有一个不同的问题处理对Web服务器的GET请求的线程运行第JBAS010152: APPLICATION ERROR: transaction still active in request with status 0和11行然后返回此时JBoss日志JBAS010152: APPLICATION ERROR: transaction still active in request with status 0 –即使线程运行第13行可以找到该事务它是否仍处于活动状态或容器是否已关闭它也值得怀疑。 AsyncServlet5.java Resource UserTransaction ut;Override protected void doGet(HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {ut.begin(); ...CompletableFutureString cf new CompletableFuture();service.foo(cf, pw); ...cf.whenCompleteAsync((s, t)-{...ut.commit(); // exception: BaseTransaction.commit - ARJUNA016074: no transaction!}); } 事务显然依赖于线程和TLS。 但这不仅仅是依赖TLS的事务。 以JPA为例该JPA被配置为直接在TLS中存储会话即与数据库的连接 或者被配置为将该会话的范围限定为当前的JTA事务 而该事务又依赖于TLS。 或以使用从EJBContextImpl.getCallerPrincipal提取的Principal进行安全性检查为例该Principal对AllowedMethodsInformation.checkAllowed进行调用然后再调用使用TLS的CurrentInvocationContext并仅返回如果在TLS中未找到任何上下文而不是进行适当的权限检查如第112行所示。 这些对TLS的依赖意味着在使用CompletableFuture或Java SE fork-join池或其他线程池无论是否由容器管理时许多标准Java EE功能将不再起作用。 公平起见对于Java EE我在这里所做的事情都是按设计的 规范实际上禁止在EJB容器中启动新线程。 我记得十多年前我曾经使用过旧版本的Websphere进行过一次测试–启动线程会引发异常因为容器确实严格遵守规范。 这是有道理的不仅因为线程数应由容器管理还因为Java EE对TLS的依赖意味着使用新线程会导致问题。 从某种意义上讲这意味着使用CompletableFuture是非法的因为它使用了不受容器管理的线程池该池由JVM管理。 使用Java SE的ExecutorService也是如此。 Java EE 7的ManagedExecutorService是一个特例-它是规范的一部分因此您可以使用它但是您必须了解这样做的含义。 EJB上的Asynchronous批注也是如此。 结果是可以在Java EE容器中编写异步非阻塞应用程序但是您确实必须知道自己在做什么并且可能必须手动处理安全性和事务之类的事情这确实是个问题。首先使用Java EE容器的原因。 那么是否有可能编写一个容器来消除对TLS的依赖以克服这些限制 的确如此但是解决方案不仅仅取决于Java EE。 该解决方案可能需要更改Java语言。 许多年前在依赖注入之前我曾经写过POJO服务它在方法之间传递了JDBC连接即作为服务方法的参数。 我这样做是为了可以在同一事务内即在同一连接上创建新的JDBC语句。 我所做的与JPA或EJB容器所需要做的事情并没有什么不同。 但是现代框架没有使用TLS作为显式传递连接或用户之类的东西的方式而是使用TLS作为集中存储“上下文”的位置例如连接事务安全信息等。 只要您在同一线程上运行TLS就是隐藏此类样板代码的好方法。 让我们假装TLS从未被发明过。 我们如何在不强制每个方法都将其作为参数的情况下传递上下文 Scala的implicit关键字是一种解决方案。 您可以声明参数可以隐式定位这使编译器将其添加到方法调用中成为问题。 因此如果Java SE引入了这种机制则Java EE不需要依赖TLS我们可以构建真正的异步应用程序在该应用程序中容器可以像今天一样通过检查注释来自动处理事务和安全性 也就是说当使用同步Java EE时容器会知道何时提交事务-在启动事务的方法调用结束时。 如果您异步运行则需要显式关闭事务因为容器不再知道何时执行此操作。 当然保持不阻塞的需要以及因此不依赖TLS的需求在很大程度上取决于当前的方案。 我不相信我今天在这里描述的问题是当今的普遍问题而是它们是处理市场细分市场的应用程序所面临的问题。 只需看一下似乎为优秀的Java EE工程师提供的工作数量而同步编程就是其中的标准。 但是我确实相信规模更大的IT软件系统会变得越来越多它们处理的数据越多阻塞API就会成为一个问题。 我还认为当前硬件增长速度的下降使这个问题更加复杂。 有趣的是Java是否a是否需要跟上异步处理的趋势以及bJava平台是否会采取行动来固定对TLS的依赖。 翻译自: https://www.javacodegeeks.com/2015/08/is-asynchronous-ejb-just-a-gimmick.htmlejb能调用另一个ejb吗
http://www.huolong8.cn/news/61737/

相关文章:

  • dw做的网站怎么做后台天堂2免费服务器
  • 天翼电子商务有限公司seo服务销售招聘
  • 杭州做企业网站的公司在线crm什么软件好
  • 网站开发设计过程wordpress更新失败
  • 做网站视频是什么专业谈谈什么是网络营销
  • 福建中兴建设有限公司网站威远移动网站建设
  • 企业微信网站怎么建设建设完网站成功后需要注意什么问题
  • 东阿做网站路桥网站设计
  • 天津小型企业网站设计电子商务网站软件建设的核心
  • 青岛鑫隆建设集团网站wordpress 文章页 模板
  • 海珠商城网站建设用ih5做微网站
  • 上传网站根目录用织梦建网站
  • 桂林哪里学建设网站阿里云域名注册续费
  • 百度喜欢什么样的网站北京朝林建设集团网站
  • 成都做公司网站服装设计好找工作吗
  • 建设网站尺寸多少制作相册影集app
  • 运城网站建设报价wordpress转hexo
  • 中国建设银行官网站基金查询网站建设技术协议书
  • 怎么修改网站的源代码中国纪检监察报理论版
  • 西安 网站建设 1会计实帐培训
  • 个人做网站犯法吗用自己头像做的圣诞视频网站
  • 商品展示的网站源码百度推广做的网站可以用吗
  • 长春网站建设模板样式竹制品网站怎么做
  • 方正网站制作如何建立微信公众号 免费
  • 公司网站应该包括哪些内容代理网络游戏
  • 平面设计培训班学费一般多少钱建站seo是什么
  • 建设部网站官网 取消八大员wordpress充值会员插件
  • 免费的企业黄页网站永久免费鞍山网络
  • 网站的建设与管理的心得体会建设部网上办事大厅
  • 山东网站建设价格实惠网络规划设计师考纲教材改版新旧对比