Pregunta

Quiero evitar esta excepción con DBUnit en el mismo lugar:

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

Esto sucede cuando se trata de leer los metadatos de columna de la tabla. El código de hacer esto es el siguiente:

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

conexión siendo una instancia MsSqlConnection. Al principio pensé que era un problema de red, pero hay dos problemas con esta teoría. En primer lugar el servidor que ejecuta la prueba y la base de datos son las dos máquinas virtuales en el mismo servidor Xen, así que no hay red real. En segundo lugar, aunque el problema es inconsistente, que ocurre en el mismo lugar cada vez. Hay más de 100 pruebas de bases de datos, pero esto mismo es el que falla (cuando falla).

Cualquier persona ha funcionado a través de un problema similar? Cualquier ideas?

¿Fue útil?

Solución

Después de un poco de juego significativa con esto, no había otro código de prueba de código que estaba leyendo los metadatos, pero no cerrar el conjunto de resultados. El problema ahora se fue.

Mi teoría es la siguiente. Con el fin de obtener los metadatos de la base de datos de MSSQL, tiene que conectarse a una base de datos diferente a la conexión actual tiene. Una forma de hacerlo es cambiar las bases de datos (hay un comando de uso en MSSQL). El problema con este enfoque es que se podría estropear su transacción con la conexión actual, y introduciría problemas de threads si más de un hilo accede a la misma conexión.

Por lo tanto, la solución era probable que se abra una conexión independiente bajo el capó, pero que comparten un objeto de conexión para la conexión global, si no para toda la máquina virtual. JDBC sólo expone un conjunto de resultados que puede ser cerrado, por lo que puede haber puesto un finalizador que cierra la conexión si no se ha llamado de cerca el conjunto de resultados y cerrado por sí mismo. El problema con esto es que si algo más está leyendo los metadatos, al mismo tiempo, tiene su conexión cerrada de debajo de ella, de ahí mi accidente.

Dado que estas ejecuciones de prueba estaban sucediendo en una ruta de código muy consistente, es ciertamente posible que el patrón de uso de la memoria era funcionan bastante estable para funcionar, la recolección de basura causa a ocurrir al mismo tiempo, pero no siempre a la misma hora , que se ajusta a la observación de que no siempre se había estrellado en el mismo lugar.

Esa es la teoría. No estoy seguro de cómo lo confirman, pero a menos que el problema viene de vuelta, que es mi suposición. Lección aprendida:. Cierre siempre el conjunto de resultados de la lectura de los metadatos (y en general)

Edit (después de mucho tiempo): Aunque en general lo anterior todavía puede ser cierto, había otro problema ocurre en el código - que estaba utilizando un finalizador en sí. Así que tenía una envoltura alrededor de una conexión que estaba cerrando la conexión en el finalizador, pero dejando que la conexión esté expuesto a otros. Otra regla de codificación importante:. Si su finalizador cierra los recursos siempre asegurarse de que nada se puede acceder a esos recursos sin tener una referencia a la clase que contiene los

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top