Pergunta

Além disso, o objeto que está sendo definido deve ser seguro para garantir que sabemos o que o estado do objeto armazenado na sessão é conhecido.

Além disso, eu estava lendo na web que alguns sugerem usar:

synchronized(session) {
  session.setAttribute("abc", "abc");
}

Esta é uma sugestão válida?

Foi útil?

Solução

Não, eles não são seguros para fios, de acordo com a IBM - Teoria e prática Java: Todos os aplicativos da Web com estado estão quebrados?. Você precisa sincronizar.

Como httpssession não é seguro Do Java Ranch também pode ser útil.

Outras dicas

Servlet 2.5 Spec:

Vários servlets que executam threads de solicitação podem ter acesso ativo ao mesmo objeto de sessão ao mesmo tempo. O contêiner deve garantir que a manipulação de estruturas de dados internas que representam os atributos da sessão seja realizada de maneira threadSafe. O desenvolvedor tem a responsabilidade pelo acesso do ThreadSafe aos próprios objetos de atributo. Isso protegerá a coleta de atributos dentro do objeto HTTPSession do acesso simultâneo, eliminando a oportunidade de um aplicativo fazer com que essa coleção seja corrompida.

Isso é seguro:

// guaranteed by the spec to be safe
request.getSession().setAttribute("foo", 1);

Isto é não seguro:

HttpSession session = request.getSession();
Integer n = (Integer) session.getAttribute("foo");
// not thread safe
// another thread might be have got stale value between get and set
session.setAttribute("foo", (n == null) ? 1 : n + 1);

Isto é não garantido para estar seguro:

// no guarantee that same instance will be returned,
// nor that session will lock on "this"
HttpSession session = request.getSession();
synchronized (session) {
  Integer n = (Integer) session.getAttribute("foo");
  session.setAttribute("foo", (n == null) ? 1 : n + 1);
}

Vi essa última abordagem defendida (incluindo os livros J2EE), mas não é garantido que funcione pela especificação do servlet. Você poderia Use o ID da sessão para criar um mutex, mas deve haver uma abordagem melhor.

Não. E como você não deseja que o mesmo cliente (com sessão) faça solicitações simultâneas, você deve serializar em serializar essas solicitações como o AbstractController faz na primavera MVC

De certa forma, isso depende do design do seu cliente.

Você tem a oportunidade, em seu design da web, para um único cliente ter várias solicitações simultâneas excelentes usando a mesma sessão HTTP? Isso parece difícil de fazer, a menos que você amarre uma única sessão HTTP a vários soquetes. (AKA, Ajax) Com falta de fazer isso, o acesso HTTP de um determinado cliente será um único thread no que diz respeito ao servidor, o que significa que uma única sessão é efetivamente segura.

A sincronização de seus objetos de sessão tornará o aplicativo mais seguro contra mudanças futuras que tornam seu aplicativo da Web capaz de ter várias solicitações simultâneas, para que não seja uma má idéia. Nas implementações modernas de Java, a sincronização não tem o grande custo que estava anteriormente associado a ele, especialmente quando a sincronização geralmente não é contendida. Se o seu aplicativo usar o AJAX, o que implica que você espera várias solicitações simultâneas de voo ao seu servidor da Web, a sincronização é uma obrigação.

Eles não são, mas na maioria das vezes, seus clientes apenas os acessam com um único thread.

Clientes diferentes terão tópicos diferentes e cada um terá sua própria sessão.

Como Eddie aponta, uma situação em que você pode enfrentar dois threads que acessam a mesma sessão são duas chamadas de Ajax estão tentando modificar o mesmo atributo de sessão. Caso contrário, você não terá problemas.

A sessão não é segura para thread e nem os métodos de definição não são garantidos para serem seguros. Em geral, em um contêiner de servlet, você deve assumir que está em um ambiente com vários rosqueados e nenhuma ferramenta fornecida é segura.

Isso também vale para os objetos que você armazena na sessão. A sessão em si não manipulará o objeto armazenado, mas você pode recuperar o objeto em diferentes encadeamentos e tentar manipulá -lo. Cabe a você examinar seu próprio código para ver se as condições de corrida são possíveis.

O exemplo de código que você postou é válido, mas o problema pode existir além do escopo limitado do seu exemplo. Ele garante que não há condições durante a configuração da sessão, mas não há nada que impeça um outro thread para substituir o conjunto. Se o código em sua solicitação depende do valor permanecendo inalterado, você ainda poderá estar com problemas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top