UCanAccess"无法访问该文件,因为它正被另一个进程使用"

时间:2018-02-16 07:12:44

标签: ms-access ucanaccess

以下使用Ucanaccess Jdbc驱动程序从Microsoft Access文件Filename.accdb获取连接的代码。但是在运行此代码时,它会像File已经被使用一样抛出异常。

但我想在其他应用程序使用MSAccess数据库文件的同时使用它。

      //Code for connecting with MS Access Database
            public void getConnection(){
               Connection connection = null;
               Statement statement = null;
               ResultSet resultSet = null;
                    try {
                        Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
                    } catch (ClassNotFoundException cnfex) {
                        logger.error("Problem in loading or "
                                + "registering MS Access JDBC driver " + cnfex);
                    }

                    String dbURL = "jdbc:ucanaccess://" + msAccDB;
                    logger.info("DB File Url = " + msAccDB);
                    try {
                        DriverManager.registerDriver(new UcanaccessDriver());
                        connection = DriverManager.getConnection(dbURL);
                    } catch (SQLException ex) {
                        logger.error(ex);
                    }
                    return connection;
            }

虽然我运行上面的代码得到了例外:

  

net.ucanaccess.jdbc.UcanaccessSQLException:UCAExc ::: 4.x.x E:\ FileName.accdb(进程无法访问该文件,因为它正由另一个进程使用)                   在net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:231)                   在java.sql.DriverManager.getConnection(DriverManager.java:664)                   在java.sql.DriverManager.getConnection(DriverManager.java:270)                   .................................................. ..............                   .................................................. .............                   .................................................. .............                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)                   at java.lang.reflect.Method.invoke(Method.java:498)                   at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)                   在com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)                   at java.lang.reflect.Method.invoke(Method.java:498)                   在sun.launcher.LauncherHelper $ FXHelper.main(LauncherHelper.java:767)               引起:java.io.FileNotFoundException:E:\ Retail Expert Data \ Pos.accdb(进程无法访问该文件,因为它正由另一个进程使用)                   在java.io.RandomAccessFile.open0(本机方法)                   在java.io.RandomAccessFile.open(RandomAccessFile.java:316)                   在java.io.RandomAccessFile。(RandomAccessFile.java:243)                   在com.healthmarketscience.jackcess.impl.DatabaseImpl.openChannel(DatabaseImpl.java:489)                   在com.healthmarketscience.jackcess.impl.DatabaseImpl.open(DatabaseImpl.java:381)                   在com.healthmarketscience.jackcess.DatabaseBuilder.open(DatabaseBuilder.java:252)                   在net.ucanaccess.jdbc.DefaultJackcessOpener.open(DefaultJackcessOpener.java:35)                   在net.ucanaccess.jdbc.DBReference。(DBReference.java:169)                   at net.ucanaccess.jdbc.DBReferenceSingleton.loadReference(DBReferenceSingleton.java:51)                   在net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:90)                   ......还有17个

5 个答案:

答案 0 :(得分:0)

对于这种类型的场景,最好迁移到SQL服务器,这样可以比Access更好地(更安全,更快)地处理多用户访问,同时通常保留兼容的数据结构。

答案 1 :(得分:0)

另一个应用程序已执行" Open Exclusive"在数据库文件上。因此,没有其他进程可以同时打开数据库。

如果您希望两个应用程序同时访问数据库,则需要让另一个应用程序以非独占模式打开数据库。此外,请注意此博客文章中描述的限制:

Multiuser concurrent write access

答案 2 :(得分:0)

确保Microsoft Access应用程序已拆分 - 前端文件链接到后端表。然后复制前端文件供您自己专用。

在Access的多用户设置中 - 必须将其拆分,并且每个用户都必须拥有自己的前端文件。

答案 3 :(得分:0)

有人建议我使用C#Dot Net。我试图访问MSAccess数据库令人惊讶它与OleDBConnection一起工作,而Microsoft Access文件正在与其他应用程序一起使用,并且文件也已打开。

结帐解决方案

如果我们使用另一种语言,如C#。

当其他应用程序正在使用Ms访问数据库文件时,绝对可以访问它。

public static OleDbConnection GetMSAccessDatabaseConnection(){

// If accdb file password ecrypted 
string ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + file_path + ";Jet OLEDB:Database Password=" + your_password + ";";

// Without password
string ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + file_path + ";Persist Security Info=False;";                

try{
        return new OleDbConnection(ConnectionString);
    }
catch(Exception ex){
     // Log your Exception
        return null;
    }
}

答案 4 :(得分:0)

UCanAccess不支持该功能。它需要对数据库文件的独占访问权。

https://ucanaccess.blogspot.com/2017/07/multiuser-concurrent-write-access.html

根据我的经验,只要您不通过UCanAccess更新数据库,数据库文件就不会损坏。尽管不能保证...

您可以改用jdbc-odbc-bridge。您可以通过Google搜索如何将桥从Java 7迁移到Java 8,以便可以使用所有酷炫的Java 8功能,还可以在Wine中配置odbc,以便您的Java应用程序可以在支持Windows jre / jdk的Linux上运行jdbc-odbc-bridge。但是,由于数据库文件位于“ E:”驱动器上,因此我假设您使用Windows,因此不需要Wine。

如果情况相反,您还可以设置配置了Wine,windows-java和odbc的通用Docker容器,以便您可以轻松启动运行jar文件的容器并从主机文件系统访问数据库文件。它有点慢,但工作正常,除了调试非常慢之外。

这是我计划解决类似问题的方法。它很丑陋(是的,真的,真的,真的很丑陋),但是它只是暂时的,将允许逐步地从Microsoft Access过渡到jdbc支持的数据库,而不必在Windows上运行。

我将从UCanAccess和

开始
    <dependency>
        <groupId>net.ttddyy</groupId>
        <artifactId>datasource-proxy</artifactId>
        <version>1.5.1</version>
    </dependency>

然后,我将使用ProxyDataSourceBuilder和QueryTransformer截取所有jdbc语句(来自github上的datasource-proxy,解释了用法)。所有选择都将保持不变,但创建,更新和删除将被拦截,我将手动“解析”所有查询参数(参数化查询中的所有?),并将字符串传递给文件,或者rest-api,在Wine中运行的Windows-java服务可以通过odbc和Access数据库引擎来拾取并执行它。然后,我将抛出一些异常,以防止UCanAccess实际写入Access数据库文件。 Hibernate会对失败的乐观锁定大惊小怪,但是可以捕获任何异常,以便实际的应用程序可以继续进行。

显然,这根本不是在生产环境中执行的,但是,如果证明它“稳定”了一点,我可以解决直到从Access迁移完成为止,而无需在VMWare中设置Windows开发环境,或者完全在Windows上运行应用程序。显然,这是个绝妙的绝技,但我的应用程序没有并发用户,不需要速度,没有无法从备份还原的过分重要的数据,等等。 ,所以我想尝试一下。