netbeans 如何使用到单个数据库的多个连接?

nbysray5  于 2022-12-13  发布在  其他
关注(0)|答案(2)|浏览(125)

我是堆栈溢出的新手,目前正在使用NetBeans和java制作一个桌面应用程序,让多个用户可以同时访问一个数据库。但不幸的是,我尝试了几个代码来启用行级锁定和TRANSACTION_READ_COMMITTED,这在www.example.com中有说明db.apache.org,但都不起作用。
我目前在derby中使用嵌入式数据库,通过搜索互联网,我找到了这个db.apache.org enter image description here和这个enter image description here
我不明白如何通过启用行级锁定和TRANSACTION_READ_COMMITTED来设置多用户数据库访问。
我尝试了这段代码,在其中我通过导入

import static java.sql.Connection.TRANSACTION_READ_COMMITTED;

con.setTransactionIsolation(TRANSACTION_READ_COMMITTED);

表示将隔离设定为TRANSACTION_READ_COMMITTED。
这是我的程序。
`

import java.sql.*;
import javax.swing.*;
import java.util.logging.*;
import static java.sql.Connection.TRANSACTION_READ_COMMITTED;

public class Connect_data extends javax.swing.JFrame {
    
    String temp_use, temp_pass, temp_usertype, n, s , u;
    //FROM ACCOUNT
    
    Connection con;
    Statement stmt;
    ResultSet rs;
public void DoConnect(){

        try{
    
        //Connect TO THE DATABASE
    
        String host = "jdbc:derby:C:\\DATABSE_SUB\\VERe";
        String uName = "josh";
        String uPass = "1234";
        
        
        con = DriverManager.getConnection(host, uName, uPass);
        
        stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
    
        String sql = "SELECT * FROM ADD_BTN";
        
        rs = stmt.executeQuery(sql);
    
    
        con.setTransactionIsolation(TRANSACTION_READ_COMMITTED);
    
        }catch(SQLException err){
            JOptionPane.showMessageDialog(Connect_data.this, err.getMessage());
        } 
    }
}

`
我所缺少的是启用行级锁定,老实说,我不知道如何实现它。

-- database-level property
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(
    'derby.storage.rowLocking', 'true')

在数据库服务NetBeans的execute命令中,但它不起作用。
当我运行程序时它连接到数据库,但当我运行第二个程序时它得到一个错误,这是我得到的输出。

Exception in thread "AWT-EventQueue-0" java.lang.SecurityException: sealing violation: package org.apache.derby.security is sealed
    at java.base/jdk.internal.loader.BuiltinClassLoader.getAndVerifyPackage(BuiltinClassLoader.java:906)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineOrCheckPackage(BuiltinClassLoader.java:877)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.defineOrCheckPackage(ClassLoaders.java:211)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:849)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    at org.apache.derby.jdbc.AutoloadedDriver.connect(Unknown Source)
    at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681)
    at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229)
    at New_Pack.Connect_data.DoConnect(Connect_data.java:132)
    at New_Pack.Connect_data.jButton1ActionPerformed(Connect_data.java:624)
    at New_Pack.Connect_data$7.actionPerformed(Connect_data.java:580)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
    at java.desktop/java.awt.Component.processEvent(Component.java:6391)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

我期待着这将锻炼,但我找不到答案。我需要帮助。

pxy2qtax

pxy2qtax1#

这里有多个问题:

主要

类路径上出现了两次derby。请修复它。

次要

更重要的是,数据库可以同时管理多个连接,但当您这样使用它时,这是一个“进程内”设置,JVM本身成为数据库服务器。任何其他应用程序同时运行在同一硬件上/使用相同的底层文件作为数据存储基本上是不可能的-只有一个“数据库引擎”可以同时运行。这意味着如果只有一个JVM承载多个连接,你可以这样做,但如果你打算启动多个JVM,并让它们使用db彼此同步,就不行了。解决方案是单独运行一个实际的DB服务器。如果你要这样做,你最好选择一个好的数据库引擎,比如postgres。
如果必须在进程内运行,hsqldb或h2是更方便的全java数据库引擎。如果在进程内运行,仍然不能使用同一个后备数据存储运行2个JVM,必须有一个单独的“服务器”(如果需要,h2也可以作为服务器运行)。
第三
数据库不是这样工作的,至少我不知道有什么数据库引擎。每个“数据存储”运行一个数据库引擎,你不能启动两个独立的进程,每个进程都从相同的源数据文件运行数据库查询。这不是事务的目的,而不是配置什么隔离级别。也许有一个DB引擎使用文件系统或管道或本地TCP/IP连接来交流细节,但如果没有这样的“通信管道”,这是不可能工作的。
因此,您需要1个java进程(或者非java进程,postgres当然也可以工作)作为数据库引擎,然后每个客户端应用程序运行1个java进程,连接到数据库引擎。这是复杂的设置权利(我不知道有哪个库会在数据库引擎没有运行的时候启动它,然后在需要的时候将其拆除)。您仍然可以使用derby、h2或hsql来托管“所有java进程内数据库引擎”,但您需要检查是否有另一个java进程正在使用该数据库,并设置启动一个localhost-responsing-only TCP/IP服务器套接字,以便其他应用程序可以连接到第一个应用程序。因此第一个应用程序是唯一直接接触DB文件的应用程序。这一切都非常非常复杂,我不知道有多少库支持这个概念。可能是因为“java桌面应用程序”很少见,而“java桌面应用程序打算同时运行不止一次”更是如此。
四分之一
“行级锁定”的概念已经过时了。它几乎不可能进行测试,并且需要非常容易出错和挑剔地找出要锁定哪些行,或者需要一个非常广泛的锁定策略,这意味着应用程序无法扩展。
正确的方法是使用乐观锁定和SERIALIZABLE事务级别。任何低于SERIALIZABLE的事务级别都有各种各样的真实的令人讨厌的警告。例如,如果这是运行ATM机的伪代码:

AccountId accountId = cardReader.getAccountIdFromInsertedCard();
int requested = askUserToPickAmount();
db.startTransaction();
int balance = db.select("SELECT balance FROM account WHERE accountId = ?", accountId).singleInt();
if (balance < requested) throw new InsufficientBalanceException();
int newBalance = balance - requested;
db.update("UPDATE account SET balance = ? WHERE accountId = ?", newBalance, accountId);
db.commit();
cashEmitter.emit(requested);

这看起来很好,有事务和所有的一切,它是 * 肯定 * 打破了一切,除了串行化。如果你使SELECT .. FOR UPDATE它取决于。
serializable的一个缺点是DB偶尔会抛出一个SQLException,其状态类型代码指示(这些代码并不统一,因此您需要为每个DB引擎编写一个检测器)一个'retry exception'。重新开始。只是,因为电脑是可靠的,它会像你在街上撞到某人一样结束,只是那是一面镜子。你向左躲,他们向左躲。你撞到了对方。解决方案:引入随机性。参见以太网协议。重点是,要做到这一点真的很复杂,你不想处理任何一个。
因此,永远不要使用直接JDBC,它并不意味着要作为最终产品的API使用。他们有更好的API,并且大多数时候都是内置的(文档解释了如何正确设置并获得事务性的、自动重试的lambda等)。

gz5pxeao

gz5pxeao2#

根据共享的源代码,您将在“嵌入式”配置中运行Derby,但是由于您希望多个客户机共享同一个数据库,因此需要在Derby的“客户机-服务器”配置中运行。
以下是有关不同配置的一些介绍性文档:https://db.apache.org/derby/docs/10.15/getstart/cgsquck70629.html
在客户机-服务器配置中,Derby服务器进程(“Derby Network Server”)提供对数据库的访问,Derby客户机进程独立运行,可以在同一台物理计算机上运行,也可以在多台单独的计算机上运行,使用网络连接连接到Derby Network Server。

相关问题