2010-04-22 27 views
5

Tôi đã tạo ví dụ đơn giản với chú thích @Singleton, @Schedule và @Timeout để thử xem chúng có giải quyết được sự cố của tôi không.Dịch vụ hẹn giờ trong ejb 3.1 - lịch biểu thời gian chờ gọi

Kịch bản này là: EJB gọi chức năng 'kiểm tra' cứ 5 seccond và nếu điều kiện nhất định được đáp ứng, nó sẽ tạo bộ đếm thời gian hành động đơn sẽ gọi một số quy trình chạy trong thời trang không đồng bộ. (đó là loại hàng đợi thực hiện loại điều). Nó sau đó tiếp tục kiểm tra, nhưng trong khi quá trình chạy dài là nó sẽ không bắt đầu một số khác.

Dưới đây là mã tôi đã đưa ra, nhưng giải pháp này không hoạt động, bởi vì có vẻ như cuộc gọi không đồng bộ mà tôi đang thực hiện đang chặn phương thức @Schedule của tôi.

@Singleton 
@Startup 
public class GenerationQueue { 

    private Logger logger = Logger.getLogger(GenerationQueue.class.getName()); 

    private List<String> queue = new ArrayList<String>(); 

    private boolean available = true; 

    @Resource 
    TimerService timerService; 

    @Schedule(persistent=true, minute="*", second="*/5", hour="*") 
    public void checkQueueState() { 

     logger.log(Level.INFO,"Queue state check: "+available+" size: "+queue.size()+", "+new Date()); 

     if (available) { 

      timerService.createSingleActionTimer(new Date(), new TimerConfig(null, false)); 
     } 

    } 

    @Timeout 
    private void generateReport(Timer timer) { 

     logger.info("!!--timeout invoked here "+new Date()); 

     available = false; 

     try { 

      Thread.sleep(1000*60*2); // something that lasts for a bit 

     } catch (Exception e) {} 

     available = true; 

     logger.info("New report generation complete"); 

    } 

Tôi đang thiếu gì ở đây hoặc tôi nên thử một chương trình khác? Bất cứ ý tưởng được chào đón nhất :)

Testing với Glassfish 3.0.1 mới nhất build - quên đề cập đến

Trả lời

11

Các @ConcurrencyManagement mặc định cho độc thân là ConcurrencyManagementType.CONTAINER với mặc định @Lock của LockType.WRITE. Về cơ bản, điều đó có nghĩa là mọi phương thức (bao gồm generateReports) được đánh dấu một cách hiệu quả với từ khóa được đồng bộ hóa, có nghĩa là checkQueueState sẽ chặn trong khi generateReport đang chạy.

Cân nhắc sử dụng ConcurrencyManagement (ConcurrencyManagementType.BEAN) hoặc @Lock (LockType.READ). Nếu cả hai gợi ý không giúp được, tôi nghi ngờ bạn đã tìm thấy một lỗi Glassfish.

Ngoài ra, bạn có thể muốn liên tục = sai vì có thể bạn không cần đảm bảo rằng phương thức checkQueueState kích hoạt sau mỗi 5 giây ngay cả khi máy chủ của bạn ngoại tuyến. Nói cách khác, có thể bạn không cần hộp chứa để kích hoạt "bắt kịp" khi bạn đưa máy chủ của mình trở lại trực tuyến.

+0

Cảm ơn rất nhiều, sự cố đã được giải quyết bằng cách thay đổi tính đồng nhất thành ConcurrencyManagementType.BEAN và có, tôi sẽ thay đổi liên tục thành false :) Cảm ơn bạn đã trợ giúp. – Greg

+1

Câu trả lời hay, học được điều gì đó mới mẻ. Cảm ơn! –

Các vấn đề liên quan