batchtest.java
来自「jtds的源码 是你学习java的好东西」· Java 代码 · 共 631 行 · 第 1/2 页
JAVA
631 行
stmt.executeUpdate("insert into #testLargeBatch (val) values (0)");
PreparedStatement pstmt = con.prepareStatement(
"update #testLargeBatch set val=? where val=?");
for (int i = 0; i < n; i++) {
pstmt.setInt(1, i + 1);
pstmt.setInt(2, i);
pstmt.addBatch();
}
int counts[] =pstmt.executeBatch();
// System.out.println(pstmt.getWarnings());
assertEquals(n, counts.length);
for (int i = 0; i < n; i++) {
assertEquals(1, counts[i]);
}
pstmt.close();
ResultSet rs =
stmt.executeQuery("select count(*) from #testLargeBatch");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertFalse(rs.next());
rs.close();
stmt.close();
}
/**
* Test for bug [1180169] JDBC escapes not allowed with Sybase addBatch.
*/
public void testBatchEsc() throws Exception {
Statement stmt = con.createStatement();
stmt.execute("CREATE TABLE #TESTBATCH (ts datetime)");
stmt.addBatch("INSERT INTO #TESTBATCH VALUES ({ts '1999-01-01 23:50:00'})");
int counts[] = stmt.executeBatch();
assertEquals(1, counts[0]);
stmt.close();
}
/**
* Test for bug [1371295] SQL Server continues after duplicate key error.
*/
public void testPrepStmtBatchDupKey() throws Exception {
Statement stmt = con.createStatement();
stmt.execute("create table #testbatch (id int, data varchar(255), PRIMARY KEY (id))");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO #testbatch VALUES (?, ?)");
for (int i = 0; i < 5; i++) {
if (i == 2) {
pstmt.setInt(1, 1); // Will cause duplicate key batch will continue
} else {
pstmt.setInt(1, i);
}
pstmt.setString(2, "This is line " + i);
pstmt.addBatch();
}
int x[];
try {
x = pstmt.executeBatch();
} catch (BatchUpdateException e) {
x = e.getUpdateCounts();
}
assertEquals(5, x.length);
assertEquals(1, x[0]);
assertEquals(1, x[1]);
assertEquals(EXECUTE_FAILED, x[2]);
assertEquals(1, x[3]);
assertEquals(1, x[4]);
// Now without errors
stmt.execute("TRUNCATE TABLE #testbatch");
for (int i = 0; i < 5; i++) {
pstmt.setInt(1, i);
pstmt.setString(2, "This is line " + i);
pstmt.addBatch();
}
x = pstmt.executeBatch();
assertEquals(5, x.length);
assertEquals(1, x[0]);
assertEquals(1, x[1]);
assertEquals(1, x[2]);
assertEquals(1, x[3]);
assertEquals(1, x[4]);
}
/**
* Test for bug [1371295] SQL Server continues after duplicate key error.
*/
public void testBatchDupKey() throws Exception {
Statement stmt = con.createStatement();
stmt.execute("create table #testbatch (id int, data varchar(255), PRIMARY KEY (id))");
for (int i = 0; i < 5; i++) {
if (i == 2) {
// This statement will generate an duplicate key error
stmt.addBatch("INSERT INTO #testbatch VALUES (1, 'This is line " + i + "')");
} else {
stmt.addBatch("INSERT INTO #testbatch VALUES (" + i + ", 'This is line " + i + "')");
}
}
int x[];
try {
x = stmt.executeBatch();
} catch (BatchUpdateException e) {
x = e.getUpdateCounts();
}
assertEquals(5, x.length);
assertEquals(1, x[0]);
assertEquals(1, x[1]);
assertEquals(EXECUTE_FAILED, x[2]);
assertEquals(1, x[3]);
assertEquals(1, x[4]);
// Now without errors
stmt.execute("TRUNCATE TABLE #testbatch");
for (int i = 0; i < 5; i++) {
stmt.addBatch("INSERT INTO #testbatch VALUES (" + i + ", 'This is line " + i + "')");
}
x = stmt.executeBatch();
assertEquals(5, x.length);
assertEquals(1, x[0]);
assertEquals(1, x[1]);
assertEquals(1, x[2]);
assertEquals(1, x[3]);
assertEquals(1, x[4]);
}
/**
* Test for PreparedStatement batch with no parameters.
*/
public void testPrepStmtNoParams() throws Exception {
Statement stmt = con.createStatement();
stmt.execute("create table #testbatch (id numeric(10) identity, data varchar(255), PRIMARY KEY (id))");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO #testbatch (data) VALUES ('Same each time')");
for (int i = 0; i < 5; i++) {
pstmt.addBatch();
}
int x[];
try {
x = pstmt.executeBatch();
} catch (BatchUpdateException e) {
x = e.getUpdateCounts();
}
assertEquals(5, x.length);
assertEquals(1, x[0]);
assertEquals(1, x[1]);
assertEquals(1, x[2]);
assertEquals(1, x[3]);
assertEquals(1, x[4]);
}
/**
* Test for PreparedStatement batch with variable parameter types.
*/
public void testPrepStmtVariableParams() throws Exception {
Statement stmt = con.createStatement();
stmt.execute("create table #testbatch (id int, data int, PRIMARY KEY (id))");
PreparedStatement pstmt = con.prepareStatement("INSERT INTO #testbatch VALUES (?, convert(int, ?))");
for (int i = 0; i < 5; i++) {
pstmt.setInt(1, i);
if (i == 2) {
// This statement will require a string param instead of an int
pstmt.setString(2, "123");
} else {
pstmt.setInt(2, 123);
}
pstmt.addBatch();
}
int x[];
try {
x = pstmt.executeBatch();
} catch (BatchUpdateException e) {
x = e.getUpdateCounts();
}
assertEquals(5, x.length);
assertEquals(1, x[0]);
assertEquals(1, x[1]);
assertEquals(1, x[2]);
assertEquals(1, x[3]);
assertEquals(1, x[4]);
ResultSet rs = stmt.executeQuery("SELECT * FROM #testbatch");
assertNotNull(rs);
int i = 0;
while (rs.next()) {
assertEquals(123, rs.getInt(2));
i++;
}
assertEquals(5, i);
}
/**
* Test batched callable statements where the call has no parameters.
*/
public void testCallStmtNoParams() throws Exception {
dropProcedure("jTDS_PROC");
try {
Statement stmt = con.createStatement();
stmt.execute("create table #testbatch (id numeric(10) identity, data varchar(255))");
stmt.execute("create proc jTDS_PROC as " +
"INSERT INTO #testbatch (data) VALUES ('same each time')");
CallableStatement cstmt = con.prepareCall("{call jTDS_PROC}");
for (int i = 0; i < 5; i++) {
cstmt.addBatch();
}
int x[];
try {
x = cstmt.executeBatch();
} catch (BatchUpdateException e) {
x = e.getUpdateCounts();
}
assertEquals(5, x.length);
assertEquals(1, x[0]);
assertEquals(1, x[1]);
assertEquals(1, x[2]);
assertEquals(1, x[3]);
assertEquals(1, x[4]);
} finally {
dropProcedure("jTDS_PROC");
}
}
/**
* Helper thread used by <code>testConcurrentBatching()</code> to execute a batch within a transaction that is
* then rolled back. Starting a couple of these threads concurrently should show whether there are any race
* conditions WRT preparation and execution in the batching implementation.
*/
private class ConcurrentBatchingHelper extends Thread {
/** Connection on which to do the work. */
private Connection con;
/** Container to store any exceptions into. */
private Vector exceptions;
ConcurrentBatchingHelper(Connection con, Vector exceptions) {
this.con = con;
this.exceptions = exceptions;
}
public void run() {
try {
PreparedStatement pstmt = con.prepareStatement(
"insert into #testConcurrentBatch (v1, v2, v3, v4, v5, v6) values (?, ?, ?, ?, ?, ?)");
for (int i = 0; i < 64; ++i) {
// Make sure we end up with 64 different prepares, use the binary representation of i to set each
// of the 6 parameters to either an int or a string.
int mask = i;
for (int j = 1; j <= 6; ++j, mask >>= 1) {
if ((mask & 1) != 0) {
pstmt.setInt(j, i);
} else {
pstmt.setString(j, String.valueOf(i));
}
}
pstmt.addBatch();
}
int x[];
try {
x = pstmt.executeBatch();
} catch (BatchUpdateException e) {
e.printStackTrace();
x = e.getUpdateCounts();
}
if (x.length != 64) {
throw new SQLException("Expected 64 update counts, got " + x.length);
}
for (int i = 0; i < x.length; ++i) {
if (x[i] != 1) {
throw new SQLException("Error at position " + i + ", got " + x[i] + " instead of 1");
}
}
// Rollback the transaction, exposing any race conditions.
con.rollback();
pstmt.close();
} catch (SQLException ex) {
ex.printStackTrace();
exceptions.add(ex);
}
}
}
/**
* Test batched prepared statement concurrency. Batch prepares must not disappear between the moment when they
* were created and when they are executed.
*/
public void testConcurrentBatching() throws Exception {
// Create a connection with a batch size of 1. This should cause prepares and actual batch execution to become
// interspersed (if correct synchronization is not in place) and greatly increase the chance of prepares
// being rolled back before getting executed.
Properties props = new Properties();
props.setProperty(Messages.get(net.sourceforge.jtds.jdbc.Driver.BATCHSIZE), "1");
props.setProperty(Messages.get(net.sourceforge.jtds.jdbc.Driver.PREPARESQL),
String.valueOf(TdsCore.TEMPORARY_STORED_PROCEDURES));
Connection con = getConnection(props);
try {
Statement stmt = con.createStatement();
stmt.execute("create table #testConcurrentBatch (v1 int, v2 int, v3 int, v4 int, v5 int, v6 int)");
stmt.close();
Vector exceptions = new Vector();
con.setAutoCommit(false);
Thread t1 = new ConcurrentBatchingHelper(con, exceptions);
Thread t2 = new ConcurrentBatchingHelper(con, exceptions);
t1.start();
t2.start();
t1.join();
t2.join();
assertEquals(0, exceptions.size());
} finally {
con.close();
}
}
public static void main(String[] args) {
junit.textui.TestRunner.run(BatchTest.class);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?