我有一个Spring Batch作业正在读取指定的Access数据库文件。我正在使用uncanaccess
JDBC库来这样做。作业退出后,无论作业是否成功完成,我都需要让我的应用程序将访问文件移动到另一个文件夹。目前,我收到一个声明java.nio.file.FileSystemException
,指出它无法移动,因为它已被另一个进程使用。我假设其他过程是由于JDBC连接已打开而引起的。
Exception in thread "main" com.mycompany.weeklyimport.FileException: Failed to move file [C:\temp\hold\temp.mdb] to [C:\temp\error\temp.mdb]
at com.mycompany.weeklyimport.WeeklyImportApplication.moveFile(WeeklyImportApplication.java:365)
at com.mycompany.weeklyimport.WeeklyImportApplication.main(WeeklyImportApplication.java:91)
Caused by: java.nio.file.FileSystemException: C:\temp\hold\temp.mdb -> C:\temp\error\temp.mdb: The process cannot access the file because it is being used by another process.
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:387)
at sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:287)
at java.nio.file.Files.move(Files.java:1395)
at com.mycompany.weeklyimport.WeeklyImportApplication.moveFile(WeeklyImportApplication.java:363)
... 1 more
这是我的主程序(通过Spring Boot运行Spring作业):
@SpringBootApplication
@EnableBatchProcessing
@Slf4j
public class WeeklyImportApplication extends DefaultBatchConfigurer {
...
private static String inputFile;
private static boolean exceptionEncountered = false;
public static void main(String[] args) throws Throwable {
handleArguments(args);
ConfigurableApplicationContext context = new SpringApplicationBuilder(WeeklyImportApplication.class).listeners(new CustomLoggingConfigurationApplicationListener(logConfigurer)).run(args);
if (exceptionEncountered) {
moveFile("error");
} else {
moveFile("complete");
}
finished();
}
private static void moveFile(String folderName) {
File file = new File(inputFile);
File newPath = new File(file.getParentFile().getParentFile().getPath() + File.separator + folderName);
if (!newPath.exists()) {
if (!newPath.mkdirs()) {
throw new FileException("Failed to create folder [" + newPath.getPath() + "]");
}
}
File newFile = new File(newPath.getPath() + File.separator + file.getName());
try {
Files.move(file.toPath(), newFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
throw new FileException("Failed to move file [" + file.getPath() + "] to [" + newFile.getPath() + "]", ex);
}
}
...
我的数据源配置。我也分配给一个静态变量,以尝试在Spring退出后关闭连接。
@Configuration
public class DataSourceConfiguration {
public static SingleConnectionDataSource legacyDataSource;
@Bean(name = "importDataSource")
public DataSource importDataSource() {
SingleConnectionDataSource dataSource = new SingleConnectionDataSource();
dataSource.setDriverClassName(this.importDriver.trim());
dataSource.setSuppressClose(true);
dataSource.setUrl("jdbc:ucanaccess://" + WeeklyImportApplication.getInputFile());
return dataSource;
}
...
我尝试了以下方法:
DataSourceConfiguration.legacyDataSource.getConnection().close();
DataSourceConfiguration.legacyDataSource.destroy();
DataSourceConfiguration.legacyDataSource = null;
不知何故,该文件仍然有锁。有没有人遇到过这样的事情,或者对如何强制真正关闭文件有任何想法?
解决了
jamadei在下面的回答帮助我获得了此解决方案。相关解决方案代码:
@Bean(name = "importDataSource")
public DataSource importDataSource() {
SingleConnectionDataSource dataSource = new SingleConnectionDataSource();
dataSource.setDriverClassName(this.importDriver.trim());
dataSource.setSuppressClose(true);
dataSource.setUrl("jdbc:ucanaccess://" + WeeklyImportApplication.getInputFile() + ";SingleConnection=true");
importDataSource = dataSource;
return dataSource;
}
public static void main(String[] args) throws Throwable {
handleArguments(args);
new SpringApplicationBuilder(WeeklyImportApplication.class).listeners(new CustomLoggingConfigurationApplicationListener(logConfigurer)).run(args);
DataSourceConfiguration.importDataSource.setSuppressClose(false);
DataSourceConfiguration.importDataSource.destroy();
if (exceptionEncountered) {
moveFile("error");
System.exit(1);
} else {
moveFile("complete");
}
finished();
}
这不仅是Spring的问题,还是UCanAccess优化/缓存的副作用。您所做的事情似乎不错,但这还不够。在jdbc url中使用SingleConnection = true参数应该可以解决此问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句