Nếu tôi có một lớp Java định nghĩa dưới đây được tiêm trong ứng dụng web của tôi qua dependency injection:Xuân Singleton Chủ đề An toàn
public AccountDao
{
private NamedParameterJdbcTemplate njt;
private List<Account> accounts;
public AccountDao(Datasource ds)
{
this.njt = new NamedParameterJdbcTemplate(ds);
refreshAccounts();
}
/*called at creation, and then via API calls to inform service new users have
been added to the database by a separate program*/
public void refreshAccounts()
{
this.accounts = /*call to database to get list of accounts*/
}
//called by every request to web service
public boolean isActiveAccount(String accountId)
{
Account a = map.get(accountId);
return a == null ? false : a.isActive();
}
}
Tôi lo ngại về an toàn thread. Khung công tác Spring không xử lý các trường hợp mà một yêu cầu đang đọc từ danh sách và nó hiện đang được cập nhật bởi một danh sách khác? Tôi đã sử dụng khóa đọc/ghi trước đây trong các ứng dụng khác, nhưng tôi chưa bao giờ nghĩ về một trường hợp như trên trước đây.
Tôi đã lên kế hoạch sử dụng bean làm đĩa đơn để tôi có thể giảm tải cơ sở dữ liệu.
Bằng cách này, đây là một tiếp lên các câu hỏi dưới đây:
Java Memory Storage to Reduce Database Load - Safe?
EDIT:
Vì vậy, sẽ mã như thế này giải quyết vấn đề này:
/*called at creation, and then via API calls to inform service new users have
been added to the database by a separate program*/
public void refreshAccounts()
{
//java.util.concurrent.locks.Lock
final Lock w = lock.writeLock();
w.lock();
try{
this.accounts = /*call to database to get list of accounts*/
}
finally{
w.unlock();
}
}
//called by every request to web service
public boolean isActiveAccount(String accountId)
{
final Lock r = lock.readLock();
r.lock();
try{
Account a = map.get(accountId);
}
finally{
r.unlock();
}
return a == null ? false : a.isActive();
}
Ok, theo dõi để chấp nhận: Điều này có thể sửa chữa dễ dàng thông qua mã được bao gồm trong lớp Java này (hoặc sửa lỗi bối cảnh ứng dụng) hay không? – thatidiotguy
Những gì bạn có thể làm là sử dụng một danh sách tạm thời để thực hiện cuộc gọi đến cơ sở dữ liệu trong 'refreshAccounts()'. Khi trả về, đồng bộ hóa trên 'tài khoản' và gán lại nó cho danh sách đó. –
Tôi sẽ nói chắc chắn bộ nhớ đệm/cơ sở dữ liệu. Việc tự quản lý đồng thời là khó khăn. Với bộ nhớ đệm bạn có thể ít nhất có ghi nhớ để kiểm soát đồng thời.Nếu bạn thực sự muốn bất kỳ số lượng yêu cầu nào tôi sẽ khai báo scope = prototype. Sau đó, bạn chạy vào vấn đề tải bạn quan tâm. –