Java内存存储减少数据库负载 - 安全吗?

时间:2013-03-13 20:32:40

标签: java mysql

如果我有一个不经常更改的MySQL表(每月一次),其中包含诸如Web服务的活动用户帐户之类的信息。做以下事情有多安全:

public AccountDao
{
   List<Account> accounts;
   /*fields*/
   public AccountDao()
   {
       refreshAccounts();
   }

   public void refreshAccounts()
   {
      this.accounts = /*call to database to get list of accounts*/
   }

   public boolean isActiveAccount(String accountId)
   {
       //logic involving in memory list object above
   }
}

我会这样做是因为我必须检查用户是否拥有允许访问Web服务的每个请求的活动帐户。这样我就可以避免在每次请求时对数据库层(目前都很紧张)进行一次SQL调用。我的问题是在生产中存储这样的数据有多安全?

顺便说一句,每当通过API调用添加新用户帐户时,我都会刷新帐户列表。如上所述,这将每月发生一次到两次。

3 个答案:

答案 0 :(得分:1)

如果您在相应的数据库表发生更改时有某种触发器来更新内存中对象,那么它应该是安全的。

如果没有触发器,它就变成了正确性,也可能是政策问题。如果您的基础架构的不同部分具有不同的内存版本的数据库,会发生什么? 间隔在多长时间内可以接受多长时间添加或删除用户以及您的服务反映的更改?

答案 1 :(得分:1)

看看caching。您的库可能已经支持它,如果没有memcached是一个很好的选择。

答案 2 :(得分:1)

  1. 访问DAO中的共享状态(可能还有其调用者)需要以某种方式同步以实现线程安全。
  2. 陈旧数据可能导致错误的访问决策。由于这可能与安全相关,因此您的代码需要防弹;特别是,它需要在发生故障时可靠地工作。这使得任何基于通知的方案都不稳定 - 如果通知丢失会怎么样?
  3. 内存中凭据的生命周期延长。通过散列凭证仍然可以实现机密性(坦率地说,如果有人可以读取您的应用程序的内存,那么您还有许多其他问题)。在内存中操作密码需要攻击者能够访问堆内存,如果可以的话,你还是会丢失,因为他可以轻松地更改用于读取帐户的数据库连接。
  4. 也就是说,对于高流量的网络服务,缓存凭据听起来像是一个明智的想法,但它并非完全无足轻重。

    编辑:不,Web容器不同步线程。并发请求将由并发线程提供,如果这些请求读取和写入相同的数据,则可能导致数据竞争。例如,一个线程可以在使用新信息更新帐户时读取帐户列表,从而查看不完整的列表。