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

问题描述 投票:0回答:5

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

但我想在其他应用程序使用时同时使用MS Access数据库文件。

      //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.xx E:\ FileName.accdb(进程无法访问该文件,因为它正由另一个进程使用)net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver。 java:231)at java.sql.DriverManager.getConnection(DriverManager.java:664)at java.sql.DriverManager.getConnection(DriverManager.java:270) ................ ................................................ .. .................................................. ........... ....................................... ........................ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62 )在com.un.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java: 389)at com.sun.javafx.application.LauncherImpl.launchApplication(Launcher) Impl.java:328)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 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。 .jackcess.DatabaseBuilder.open(DatabaseBuilder.java:252)at net.ucanaccess.jdbc.DefaultJackcessOpener.open(Defaul) tJackcessOpener.java:35)net.ucanaccess.jdbc.DBReference。(DBReference.java:169)net.ucanaccess.jdbc.DBReferenceSingleton.loadReference(DBReferenceSingleton.java:51)at net.ucanaccess.jdbc.UcanaccessDriver.connect( UcanaccessDriver.java:90)......还有17个

ms-access ucanaccess
5个回答
0
投票

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


0
投票

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

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

Multiuser concurrent write access


0
投票

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

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


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;
    }
}

0
投票

UCanAccess不支持这一点。它需要对数据库文件的独占访问权限。

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

根据我的经验,只要您不通过UCanAccess更新数据库,数据库文件就不会被破坏。不保证,但......

您可以使用jdbc-odbc-bridge代替。您可以谷歌如何将桥接器从Java 7迁移到Java 8,这样您就可以使用所有酷的Java 8功能,还可以在Wine中配置odbc,以便您的Java应用程序可以在支持Windows jre / jdk的Linux上运行JDBC-ODBC桥。但是,由于数据库文件驻留在“E:”驱动器上,我假设您使用Windows,因此您不需要Wine。

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

以下是我打算解决类似问题的方法。它非常难看(是的,真的,真的,非常难看),但它只是暂时的,并且允许从Microsoft Access到jdbc支持的数据库的逐步过渡,而不必在Windows上运行东西:

我将从UCanAccess开始

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

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

显然,这不是如何在生产环境中完成的,但是如果它在某种程度上证明是“稳定的”,那么我可以直到远离Access完成迁移,而无需在VMWare中设置Windows开发环境或运行应用程序在Windows上。这显然是一个不尝试这种家庭孩子的特技,但我的应用程序没有并发用户,不需要速度,没有无法从备份恢复的过于重要的数据,等等所以我想我会试一试。

© www.soinside.com 2019 - 2024. All rights reserved.