我有一个客户陷入了EJB 3.0环境。没有@Singleton,没有bean管理的并发: - (
ejb规范禁止考虑线程管理和同步,如何实现缓存?从本质上讲,我想要一些非同步的对象缓存来进行一些代价高昂的操作。
答案 0 :(得分:1)
EJB 3.0规范第21.1.2章中说明了使用静态字段和同步的限制。它也解释了原因。
•企业bean不得使用读/写静态字段。运用 允许只读静态字段。因此,建议 企业bean类中的所有静态字段都被声明为final。
需要此规则来确保一致的运行时语义,因为 而某些EJB容器可能使用单个JVM来执行所有操作 企业bean的实例,其他人可以分发实例 跨多个JVM。
•企业bean不得使用线程 同步原语同步多个执行 实例
这与上述原因相同。同步不起作用 如果EJB容器跨越企业bean的实例 多个JVM。
如果通过单例POJO实现缓存,则可能存在以下风险:如果EJB容器跨多个JVM分布EJB实例(例如,在集群环境中),则每个JVM中实际存在多个缓存实例。
所以它取决于,
如果它对您不起作用,可能您应该考虑在EJB容器之外缓存数据,例如放入Redis或Hazelcast。
答案 1 :(得分:0)
我怀疑我是否清楚地理解你的问题!以下示例基于weblogic
和eclipselink
。
如果您正在为您的EJB使用eclipselink JPA,您可以像这样单独为每个实体使用缓存:
@Entity
@Cache(type=CacheType.SOFT)
如果需要,还可以为persistence.xml文件中的所有实体启用缓存。这在属性字段(oracle doc's link)中就是这样的:
<persistence-unit name="XYZ">
...
<class>com.stack.Test</class>
<properties>
...
<property name="toplink.cache.type.default" value="Soft"/>
...
</properties>
</persistence-unit>
缓存类型可以是不同的,如Soft,Hard,Weak,Full等。每个缓存类型都有自己的含义。您可以从here找到有关此缓存类型的更多信息。
答案 2 :(得分:0)
EJB容器中是否禁止使用volatile变量? volatile int变量提供了一些对多线程代码有用的保证。如果线程看到volatile变量的变化,则可以安全地假设它看到之前发生的所有事情。
另一个想法是@Stateful bean只实例化一次(调用将由容器序列化)。不过,我不确定实施细节。
答案 3 :(得分:0)
嗯,我认为ConcurrentSkipListMap可能是解决方案:没有同步但仍然是线程安全的。
答案 4 :(得分:0)
我将Redis和Jedis一起用于内存中的临时值。
请参阅下面的链接
https://redislabs.com/lp/redis-java/
Redis带有用于多个操作系统的安装程序。
示例:
import redis.clients.jedis.Jedis;
public class RedisStringJava {
public static void main(String[] args) {
//Connecting to Redis server on localhost
Jedis jedis = new Jedis("localhost");
System.out.println("Connected");
//set the data in redis string and expire in default time
jedis.set("param_name", "Param value");
// Get the stored data and print it
System.out.println("Stored string in redis:: "+ jedis.get("param_name"));
}
}