使用 Java JDBC 写入时 VSAM 文件锁定
Posted
技术标签:
【中文标题】使用 Java JDBC 写入时 VSAM 文件锁定【英文标题】:VSAM file locking when writing to it using Java JDBC 【发布时间】:2015-12-10 15:29:48 【问题描述】:这是我第一次尝试读写 VSAM 文件。我所做的是:
-
使用 VSE Navigator 为文件创建了地图
将 Java beans VSE 连接器库添加到我的 eclipse Java 项目中
使用下面显示的代码写入和读取 KSDS 文件。
读取文件不是问题,但是当我尝试写入文件时,它只有在我进入大型机并在运行我的 java 程序之前关闭文件时才有效,但它会锁定文件大约一个小时。您无法在大型机上打开该文件或对其进行任何操作。
任何人都可以帮助解决这个问题。是否需要为大型机上的文件设置特殊设置?为什么您首先需要关闭 CICS 上的文件才能对其进行写入?为什么它在写入文件后锁定文件?
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.*;
public class testVSAM
public static void main(String argv[])
Integer test = Integer.valueOf(2893);
String vsamCatalog = "VSESP.USER.CATALOG";
String FlightCluster = "FLIGHT.ORDERING.FLIGHTS";
String FlightMapName = "FLIGHT.TEST2.MAP";
try
String ipAddr = "10.1.1.1";
String userID = "USER1";
String password = "PASSWORD";
java.sql.Connection jdbcCon;
java.sql.Driver jdbcDriver = (java.sql.Driver) Class.forName(
"com.ibm.vse.jdbc.VsamJdbcDriver").newInstance();
// Build the URL to use to connect
String url = "jdbc:vsam:"+ipAddr;
// Assign properties for the driver
java.util.Properties prop = new java.util.Properties();
prop.put("port", test);
prop.put("user", userID);
prop.put("password", password);
// Connect to the driver
jdbcCon = DriverManager.getConnection(url,prop);
try
java.sql.PreparedStatement pstmt = jdbcCon.prepareStatement(
"INSERT INTO "+vsamCatalog+"\\"+FlightCluster+"\\"+FlightMapName+
" (RS_SERIAL1,RS_SERIAL2,RS_QTY1,RS_QTY2,RS_UPDATE,RS_UPTIME,RS_EMPNO,RS_PRINTFLAG,"+
"RS_PART_S,RS_PART_IN_A_P,RS_FILLER)"+" VALUES(?,?,?,?,?,?,?,?,?,?,?)");
//pstmt.setString(1, "12345678901234567890123003");
pstmt.setString(1, "1234567890");
pstmt.setString(2,"1234567890123");
pstmt.setInt(3,00);
pstmt.setInt(4,003);
pstmt.setString(5,"151209");
pstmt.setString(6, "094435");
pstmt.setString(7,"09932");
pstmt.setString(8,"P");
pstmt.setString(9,"Y");
pstmt.setString(10,"Y");
pstmt.setString(11," ");
// Execute the query
int num = pstmt.executeUpdate();
System.out.println(num);
pstmt.close();
catch (SQLException t)
System.out.println(t.toString());
try
// Get a statement
java.sql.Statement stmt = jdbcCon.createStatement();
// Execute the query ...
java.sql.ResultSet rs = stmt.executeQuery(
"SELECT * FROM "+vsamCatalog+"\\"+FlightCluster+"\\"+FlightMapName);
while (rs.next())
System.out.println(rs.getString("RS_SERIAL1") + " " + rs.getString("RS_SERIAL2")+ " " + rs.getString("RS_UPTIME")+ " " + rs.getString("RS_UPDATE"));
rs.close();
stmt.close();
catch (SQLException t)
catch (Exception e)
// do something appropriate with the exception, *at least*:
e.printStackTrace();
注意:操作系统是 z/VSE
【问题讨论】:
那么你的问题到底是什么?为什么写入文件需要排他锁?为什么写这么久?请尝试更具体。 我更新了我的问题。但我的问题是。为什么我需要先关闭 CICS 上的文件才能写入文件。以及为什么在我写入文件后文件锁定(无法打开、读取或写入)? 我没有看到您关闭与该文件的连接 - 这可能会使其保持打开和锁定状态。 一月感谢您的帮助! :)。我们解决了这个问题。问题是 JDBC 使用的服务器端(大型机)上的 VSE 连接器使用批处理程序。 CISC 文件是使用只有 CICS 程序可以写入而不是批处理程序的选项创建的。我们使用批处理程序可以写入的属性重新定义文件,现在它可以工作了。如果术语或解释不是关于大型机的最佳,我是一名 PC 程序员,非常抱歉。 如果你花时间回答你自己的问题(并接受它!)那就太好了,所以下一个人有一些关于如何通过搜索解决这个问题的信息。 【参考方案1】:对原始问题的简短回答是 KSDS VSAM 不是 DBMS。
正如您所发现的,您可以定义 VSAM 文件,以便可以从批处理和 CICS 更新它,但正如 @BillWoodger 指出的那样,您必须自己序列化更新。
另一种方法是从 CICS 区域进行所有更新,并让您的 Java 应用程序向 CICS 发送 REST 或 SOAP 或 MQ 消息以请求其更新。这确实需要有一个 CICS 程序来捕获来自 Java 应用程序的请求并执行更新。
【讨论】:
【参考方案2】:z/VSE 下的 IBM 大型机具有运行不同作业的不同分区。例如分区 F7 CICS、分区 F8 Batch Jobs、ETC。
当您定义一个新的 VSAM 文件时,您必须设置文件的 SHAREOPTIONS。当我定义文件时,我设置了 SHAREOPTIONS (2 3)。 2 表示只有一个分区可以写入文件。
因此,当从 Java 调用的批处理程序(在与 CICS 分区不同的分区中)试图写入文件时,它无法写入文件,除非我先在 CICS 中关闭文件。
为了修复它,我使用 SHAREOPTIONS (4 3) 重新定义了 CICS 文件。 4 表示 Mainframe 的多个分区可以写入。解决问题
下面是你设置SHAREOPTION的部分定义代码:
* $$ JOB JNM=DEFFI,CLASS=9,DISP=D,PRI=9
* $$ LST CLASS=X,DISP=H,PRI=2,REMOTE=0,USER=JAVI
// JOB DEFFI
// EXEC IDCAMS,SIZE=AUTO
DEFINE CLUSTER -
( -
NAME (FLIGHT.ORDERING.FLIGHTS) -
RECORDS (2000 1000) -
INDEXED -
KEYS (26 0) -
RECORDSIZE (128 128) -
SHAREOPTIONS (4 3) -
VOLUMES (SYSWKE) -
) -
.
.
.
【讨论】:
慢下来:“使用选项 3 和 4,您负责维护程序访问的数据的读写完整性。这些选项要求您的程序在共享时使用 ENQ/DEQ 来维护数据完整性数据集,包括 OPEN 和 CLOSE 处理。忽略写入完整性准则的用户程序可能会导致 VSAM 程序检查、丢失或无法访问记录、无法纠正的数据集故障以及其他不可预知的结果。这些选项对共享数据集。” 嘿比尔,我应该提一下我是 PC 程序员而不是大型机程序员。当您谈论我使用 ENQ/DEQ 的程序时,您是在谈论读取/写入 VSAM 文件的 CISC 程序吗? 如果两个“程序”对同一个文件有更新访问权限,他们需要有代码来对资源进行排队,完成工作,然后对资源进行解除排队。否则充其量您会不时丢失数据,最坏的情况是您会损坏无法修复的文件。将消息从您的 Java 发送到 CICS(注意字母顺序)程序以进行更新是保持简单的一种方法。另请注意,使用 SHAREOPTIONS 3 或 4,您可能/将会降低性能,即使只是读取文件也是如此。 对于大型机新手,您需要依赖大型机同事和技术支持。他们会像任何东西一样快速反弹,所以无论如何你都需要一个不同的解决方案。所以在设计的某个地方,这应该已经被覆盖了。如果您想从不同的“程序”进行多个同时更新(松散地使用术语,将 CICS 视为一个程序),那么您需要在两个/所有程序中处理它。 SHAREOPTIONS 4 有利于多次更新,但数据完整性取决于用户(程序员)。以上是关于使用 Java JDBC 写入时 VSAM 文件锁定的主要内容,如果未能解决你的问题,请参考以下文章