Bạn dường như có một số vấn đề thiết kế cơ sở dữ liệu và kiến trúc phần mềm cơ bản hơn ở đây.
Thay vì thiết lập một số lĩnh vực "hết hạn" sau một khoảng thời gian nhất định, chỉ cần lưu trữ thời gian hết hạn thực tế. Sau đó, khi người dùng thực hiện một hành động, chỉ cần kiểm tra thời gian hết hạn so với thời gian hiện tại để xem liệu lời mời có hết hạn hay không. Bằng cách đó, nó luôn hoạt động và bạn không phải lên lịch hẹn giờ hoặc quản lý các giao dịch dài hạn hoặc bất kỳ thứ gì như thế. Nó cũng ngầm liên tục trong quá trình khởi động lại chương trình/sự cố (phương pháp dựa trên bộ đếm thời gian hiện tại sẽ yêu cầu nỗ lực ngăn không cho nó hết hạn để chờ lời mời nếu chương trình bị chấm dứt trong khi bộ hẹn giờ đang chạy).
Nếu bạn muốn có thông báo hết hạn đang diễn ra, hãy thêm trường "người dùng đã được thông báo" (ví dụ) vào lời mời. Sau đó, tạo một tác vụ lặp lại đơn (bộ đếm thời gian có thể tốt cho việc này hoặc ScheduledExecutorService
) định kỳ lấy danh sách tất cả lời mời không được thông báo đã hết hạn trong một truy vấn tiêu chí duy nhất. Tắt thông báo, đặt cờ được thông báo, rửa sạch, lặp lại. Bạn có thể xếp hàng các thông báo trong một nhóm luồng ExecutorService
nếu bạn muốn, nếu thông báo mất nhiều thời gian (ví dụ: gửi email).
Đóng cửa (hoặc xấp xỉ) không phải là công cụ phù hợp cho công việc này.
Nhưng, nếu bạn phải làm điều cờ theo thời gian, thiết lập chế độ ngủ đông sang chế độ phiên đối tượng mỗi chủ đề (trên thực tế, tôi nghĩ rằng thậm chí có thể là chế độ mặc định), sau đó sử dụng một ExecutorService bơi thread (xem Executors) để lên lịch một nhiệm vụ mở giao dịch, truy vấn mời, chờ (không hẹn giờ), sau đó thực hiện và đóng giao dịch. Sau đó, toàn bộ giao dịch của bạn là trên một chuỗi nền và không có vấn đề quản lý giao dịch lạ nào bạn đang gặp phải nữa.
Thậm chí tốt hơn, hãy ngừng thử tất cả điều này trong một giao dịch chạy dài duy nhất (ví dụ: nếu người dùng muốn xóa lời mời trong khi bộ hẹn giờ của bạn đang chạy?). Mở một giao dịch rồi truy vấn lời mời rồi đóng nó lại. Sau đó, đặt bộ hẹn giờ của bạn (hoặc sử dụng ScheduledExecutorService
) và để bộ hẹn giờ mở một giao dịch, truy vấn lời mời, hết hạn lời mời, sau đó đóng nó. Có thể bạn không muốn giữ kết nối và/hoặc giao dịch db mở trong toàn bộ khoảng thời gian MAX_TIME
, không có lý do gì để làm điều đó.
Đối với điều cuối cùng, biến nonfinal không thể được đề cập đến trong các lớp bên trong vô danh vì bạn có thể không phải lúc nào đảm bảo rằng giá trị của chúng sẽ không thay đổi trước khi mã lớp vô danh đang chạy (trình biên dịch không và thường không thể, trải qua những rắc rối khi phân tích cách lớp ẩn danh được sử dụng để thực hiện bảo đảm đó). Vì vậy, nó yêu cầu final
.
Chỉ cần tuyên bố mời chính thức:
final Invite invite = ...;
Và bạn có thể sử dụng nó trong lớp ẩn danh của bạn.
Có thể tìm thấy gợi ý giải thích dưới mui xe here.
Và có bạn có thể sửa đổi các trường của invite
. Bạn không thể chỉ định lời mời cho một đối tượng mới. Nhưng như tôi đã nói, cách tiếp cận của bạn rất sôi nổi và vì vậy bạn đang gặp phải vấn đề.
Tôi đang sử dụng điện thoại của mình hoặc tôi sẽ tìm hiểu phần có liên quan của JLS cho nội dung cuối cùng. Bạn có thể tìm nó ở đó để biết thêm thông tin.
thử 'lời mời cuối cùng mời = (Mời) criteria.uniqueResult();'? – Gosu
Chỉ cần nâng cấp lên Java 8 hoặc làm điều đó ^. –
@Gosu, vì vậy nếu 'lời mời' là cuối cùng, tôi vẫn có thể thay đổi các thuộc tính trên nó bằng cách sử dụng' setExpired() '? – gwg