DbUnit和SQL Server快速插座关闭
-
20-09-2019 - |
题
我不断收到此异常用DbUnit在同一个地方:
org.dbunit.dataset.DataSetException: com.microsoft.sqlserver.jdbc.SQLServerException: Socket closed
at org.dbunit.database.DatabaseTableMetaData.getColumns(DatabaseTableMetaData.java:359)
等
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
此发生试图读取从表中的列的元数据时。这样做的代码看起来是这样的:
new DefaultTable(tableName,
Columns.getColumns(columns,
connection.createDataSet(new String[]{tableName})
.getTableMetaData(tableName).getColumns()
)
)
连接是一个MsSqlConnection实例。起初我还以为是网络问题,但有两个问题与理论。首先运行测试服务器和数据库是相同的Xen的服务器上的两个虚拟机,所以没有真正的网络。其次,虽然问题是不一致的,它在同一个地方,每次发生。有超过100个数据库的测试,但是这同样是一个失败的一个(当它失败)。
有没有人碰到类似的问题运行?任何见解?
解决方案
与此一些显著播放以后,有其他代码测试代码被读取元数据,但不关闭结果集。现在的问题就走开了。
我的理论如下。为了获得数据库的元数据在MSSQL,你必须连接到不同的数据库比目前连接了。要做到这一点的方法之一是改变数据库(有MSSQL中使用一个命令)。用这种方法的问题是,你可以弄乱你的交易与当前连接,如果多个线程访问相同的连接将引入线程问题。
因此,该解决方案是可能打开引擎盖下单独的连接,但是,共享一个连接对象的整体连接,如果不是针对整个VM。 JDBC只公开一个结果集,可以关闭,所以他们可能已经把其关闭,如果你还没有叫接近的结果集,并关闭它自己的连接的终结。但问题是,如果别的东西是阅读的同时,元数据,它有它的连接从它下面收出,所以我崩溃。
考虑到这些试验运行是在完全相同的时间发生它肯定是可能的内存使用模式是相当稳定的运行运行,导致垃圾回收在同一时间发生了非常一致的代码路径上,但并非总是如此,符合该观察,它并不总是以完全相同的地方坠毁。
这是理论。我不知道如何进行确认,但除非问题回来,这是我的假设。获得的经验:总是读取元数据(和一般的)关闭结果集
EDIT(很长的时间后):虽然在一般上述可能仍然是真实的,有一个在代码正在进行另一个问题 - 它是使用一个终结本身。所以,你必须围绕这是关闭的终结连接,但让连接被其他人连接的包装。另一个重要的编码规则:如果你的终结关闭资源始终确保没有任何东西可以访问这些资源,而不必包含它们的类的引用