【问题标题】:Generating Id unique in EJB session bean in a Java Web Application在 Java Web 应用程序的 EJB 会话 bean 中生成唯一 ID
【发布时间】:2018-11-22 10:54:45
【问题描述】:

我尝试生成唯一的长 ID。我在服务中生成它,这就是服务:

package x.y.z;

import java.util.Map; 
import java.util.concurrent.ConcurrentHashMap;
import javax.ejb.Startup; 
import javax.ejb.Stateless;

import  x.y.NiceObject;


@Stateless 
@Startup 
public class Transacciones {

     private  long idTransaccion = 0l;

     static Map<Long, NiceObject> mapaTransacciones = new ConcurrentHashMap<>();         

     public Transacciones() {
     }

    public long getIdTransaccion() {        
      ++idTransaccion;      
       return idTransaccion;    
     }

    public void setIdTransaccion(long idTransaccion) {
        idTransaccion = idTransaccion; 
    }

    public Map<Long, NiceObject> getMapaTransacciones() { 
        return mapaTransacciones;   
    }

    public void setMapaTransacciones(Map<Long, NiceObject> mapaTransacciones) {          
    this.mapaTransacciones = mapaTransacciones;     
    } 
}

我有一个托管 bean,我从那里调用此服务并尝试使用此生成的 id。这是bean的方法:

@EJB
private Transacciones transaccionService;


    public String capture() {
        ExecutorService service = Executors.newFixedThreadPool(2);
        try {
            long idTransaccion = 
            transaccionService.getIdTransaccion();
            method1(idTransaccion);
            service.submit(() -> {
                method2(idTransaccion);
            });
        } finally {
            if (service != null)
                service.shutdown();
        }
        return null;
    }

问题是在某个时间的某个地方,它失败了;因为我希望得到这样的生成 ID:

1,2,3,4,5,6.......

但我明白了:

1,2,1,3,4,2,...

在这一行:

long idTransaccion = transaccionService.getIdTransaccion();

会有什么问题。请记住,我有一个 SessionScope 的托管 Bean,我从该 Bean 在 EJB 中调用此方法。

如有任何帮助,请提前致谢!

【问题讨论】:

  • 会话bean中的“无状态”是什么意思(你用@Stateless注释Transacciones)?
  • 您可以将当前的 transactionId 保存到数据库并从磁盘读取它,而不是将其保存在 Transacciones 实例中吗?
  • Tuby 谢谢请看我的更新。数据库是一个解决方案。但我认为对数据库的访问比在内存中访问更慢......我选择这个解决方案就是因为这个原因。
  • “会有什么问题。请记住,我有一个 SessionScope 的托管 Bean,我在 EJB 中调用此方法。”。该问题与调用无状态会话 bean 的位置无关。来自 ejb 3 规范:无状态会话 bean (1) 从一个方法调用到下一个方法调用保持无状态。 (2) 没有会话状态,也不是专门为客户服务的。
  • 在无状态会话 bean Transacciones 中不能有 idTransaccion 实例变量。无国籍意味着 - 没有国家;这意味着没有实例变量。您必须找到其他方法来创建、存储和检索唯一 ID。尝试使用“ejb generate unique ids”之类的搜索字符串搜索网络(Google)。

标签: java ejb-3.0


【解决方案1】:

有一个无状态 bean 池。并且每个调用都被委托给不同的实例,实际上您调用了一个代理方法,它将您的调用委托给了池的一个实例。无法保证即使对 bean 的两次连续调用(注入到您的 bean 中)也使用同一个 bean。所以当重新生成 1 时,就意味着它使用了另一个 bean。您可以使用单例而不是无状态。 正如@prasad_3 所说,您不能在无状态 bean 中拥有状态。

【讨论】:

    【解决方案2】:

    将 idTransaccion 定义为静态变量。

    【讨论】:

    • 谢谢桑托什。但我想:我没有实例化服务的新对象。为什么需要在这个类中将这个变量设为静态?
    • @FernandoPie 。我认为您的会话正在丢失,因为您获得了随机值。
    • 谢谢。它可能是。但是制作静态有什么帮助呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 2013-12-23
    • 2014-04-20
    • 2013-07-07
    • 1970-01-01
    • 2014-10-13
    • 1970-01-01
    相关资源
    最近更新 更多