Question

Je continue à obtenir cette exception avec DBUnit au même endroit:

org.dbunit.dataset.DataSetException: com.microsoft.sqlserver.jdbc.SQLServerException: Socket closed
at   org.dbunit.database.DatabaseTableMetaData.getColumns(DatabaseTableMetaData.java:359)

etc.

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Socket closed
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(Unknown Source)
at com.microsoft.sqlserver.jdbc.TDSChannel.read(Unknown Source)
at com.microsoft.sqlserver.jdbc.TDSReader.readPacket(Unknown Source)
at com.microsoft.sqlserver.jdbc.TDSReader.readPacket(Unknown Source)
at com.microsoft.sqlserver.jdbc.TDSCommand.startResponse(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(Unknown Source)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQueryInternal(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerDatabaseMetaData.getResultSetFromStoredProc(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerDatabaseMetaData.getResultSetWithProvidedColumnNames(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerDatabaseMetaData.getColumns(Unknown Source)
at org.dbunit.database.DefaultMetadataHandler.getColumns(DefaultMetadataHandler.java:52)
at org.dbunit.database.DatabaseTableMetaData.getColumns(DatabaseTableMetaData.java:315)
... 15 more

Cela se produit lorsque vous essayez de lire les métadonnées de colonne de la table. Le code faisant cela ressemble à ceci:

 new DefaultTable(tableName,
                    Columns.getColumns(columns,
                            connection.createDataSet(new String[]{tableName})
                                    .getTableMetaData(tableName).getColumns()
                    )
            )

liaison étant une instance MsSqlConnection. Au début, je pensais que c'était un problème de réseau, mais il y a deux problèmes avec cette théorie. D'abord le serveur exécutant le test et la base de données sont les deux machines virtuelles sur le même serveur Xen, donc il n'y a pas de réseau réel. En second lieu, bien que le problème est incompatible, il arrive au même endroit à chaque fois. Il y a plus de 100 tests de base de données, mais ce même est celui qui échoue (quand il échoue).

Quelqu'un at-il courir à travers un problème similaire? Toute autre idée?

Était-ce utile?

La solution

Après une importante jeu avec cela, il y avait un autre code de test de code qui a été la lecture des métadonnées, mais ne pas fermer le jeu de résultats. Le problème est allé maintenant loin.

Ma théorie est la suivante. Afin d'obtenir les métadonnées de base de données MSSQL, vous devez vous connecter à une base de données différente de la connexion en cours a. Une façon de le faire est de changer les bases de données (il y a une commande utilisation dans MSSQL). Le problème avec cette approche est que vous pourriez gâcher votre transaction avec la connexion en cours, et introduirait des problèmes de filetage si plus d'un thread accède à la même connexion.

Alors, la solution était susceptible d'ouvrir une connexion séparée sous le capot, mais partageant un objet de connexion pour la connexion globale, sinon pour toute la machine virtuelle. JDBC expose uniquement un jeu de résultats qui peut être fermé, afin qu'ils puissent avoir mis un finaliseur qui ferme la connexion si vous ne l'avez pas appelé près du jeu de résultats et fermé vous-même. Le problème avec cela est que si quelque chose d'autre est en train de lire les métadonnées en même temps, il a sa connexion fermée de dessous, d'où mon accident.

Étant donné que ces séries de tests se passait sur un chemin de code très cohérent, il est certainement possible que le modèle d'utilisation de la mémoire a été exécuté assez stable pour fonctionner, parce que la collecte des ordures se produire en même temps, mais pas toujours exactement en même temps , ce qui correspond l'observation qu'il ne tombe pas en panne toujours exactement au même endroit.

Telle est la théorie. Je ne sais pas comment le confirmer, mais à moins que le problème revient, c'est mon hypothèse. Leçon apprise:. Toujours fermer le jeu de résultats à la lecture des méta-données (et en général)

EDIT (après une longue période): Bien qu'en général ce qui précède peut encore être vrai, il y avait un autre problème se passe dans le code - il utilisait un finaliseur lui-même. Donc, vous avez eu une enveloppe autour d'une connexion qui refermait la connexion dans le finaliseur mais laisser la connexion être exposé à d'autres. Une autre règle de codage importante. Si votre ferme finaliseur ressources toujours faire en sorte que rien ne peut accéder à ces ressources sans avoir une référence à la classe les contenant

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top