Como comentei antes, é porque os soquetes que estão abertos e conectados ao banco de dados não percebem que a conexão foi perdida, então eles permaneceram conectados até que o tempo limite do soquete do SO seja acionado, o que eu li pode ser geralmente em cerca de 30 minutos .
Para resolver o problema, você precisa substituir o tempo limite do soquete em sua string de conexão JDBC ou na configuração/propriedades da conexão JDNI para definir o socketTimeout param para um tempo menor.
Tenha em mente que qualquer conexão maior que o valor definido será encerrada, mesmo que esteja sendo usada (não consegui confirmar isso, foi o que li).
Os outros dois parâmetros que mencionei no meu comentário são connectTimeout e autoReconexão .
Aqui está minha string de conexão JDBC:
jdbc:(...)&connectTimeout=15000&socketTimeout=60000&autoReconnect=true
Eu também desabilitei o cache DNS do Java fazendo
java.security.Security.setProperty("networkaddress.cache.ttl" , "0");
java.security.Security.setProperty("networkaddress.cache.negative.ttl" , "0");
Faço isso porque o Java não respeita os TTL's e, quando ocorre o failover, o DNS é o mesmo, mas o IP muda.
Como você está usando um servidor de aplicativos, os parâmetros para desativar o cache DNS devem ser passados para a JVM ao iniciar o glassfish com -Dnet e não o próprio aplicativo.