下面列出了java.sql.Connection#setSavepoint ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Inserts one row into a table with an auto-generated column while inside
* a savepoint unit, does a rollback, then gets keys after an insert
* into a table without an auto-generated column.
* Old master Test 13.
* Expected result: ResultSet has one row with a non-NULL key, and the
* key value should be the same before and after the rollback.
* @throws SQLException
*/
public void testGetKeyAfterSavepointRollback() throws SQLException
{
Connection conn = getConnection();
Statement s = createStatement();
Savepoint savepoint1 = conn.setSavepoint();
int expected=1;
s.execute("insert into t11_AutoGen(c11) values(99)",
Statement.RETURN_GENERATED_KEYS);
int keyval = getKeyValue (s.getGeneratedKeys());
assertEquals("Key value before rollback", expected, keyval);
conn.rollback(savepoint1);
s.execute("insert into t21_noAutoGen values(39, 'true')",
Statement.RETURN_GENERATED_KEYS);
keyval = getKeyValue (s.getGeneratedKeys());
assertEquals("Key value after rollback", expected, keyval);
s.close();
}
/**
* Test 7a: BUG 4468 - should not be able to pass a savepoint from a
* different transaction for release/rollback
*/
public void testSwapSavepointsAcrossConnectionAndRelease()
throws SQLException {
Connection con = getConnection();
Connection con2 = openDefaultConnection();
con2.setAutoCommit(false);
Savepoint savepoint1 = con2.setSavepoint("s1");
Statement s = createStatement();
s.executeUpdate("INSERT INTO T1 VALUES(2,1)");
con.setSavepoint("s1");
try {
con.releaseSavepoint(savepoint1);
fail("FAIL 7a - releasing a another transaction's savepoint did "
+ "not raise error");
} catch (SQLException se) {
// Expected exception.
if (usingEmbedded()) {
assertSQLState("3B502", se);
} else if (usingDerbyNetClient()) {
assertSQLState("XJ097", se);
}
}
con.commit();
con2.commit();
}
/**
* Test 47 multiple tests for getSavepointId()
*/
public void xtestGetSavepoint() throws SQLException {
Connection con = getConnection();
Savepoint savepoint1 = con.setSavepoint();
Savepoint savepoint2 = con.setSavepoint();
savepoint1.getSavepointId();
savepoint2.getSavepointId();
con.releaseSavepoint(savepoint2);
savepoint2 = con.setSavepoint();
savepoint2.getSavepointId();
con.commit();
savepoint2 = con.setSavepoint();
savepoint2.getSavepointId();
con.rollback();
savepoint2 = con.setSavepoint();
savepoint2.getSavepointId();
con.rollback();
}
/**
* Test 7b - swap savepoints across connections
*/
public void testSwapSavepointsAcrossConnectionsAndRollback()
throws SQLException {
Connection con = getConnection();
Connection con2 = openDefaultConnection();
con2.setAutoCommit(false);
Savepoint savepoint1 = con2.setSavepoint("s1");
Statement s = createStatement();
s.executeUpdate("INSERT INTO T1 VALUES(2,1)");
con.setSavepoint("s1");
try {
con.rollback(savepoint1);
fail("FAIL 7b - rolling back a another transaction's savepoint "
+ "did not raise error");
} catch (SQLException se) {
// Expected exception.
if (usingEmbedded()) {
assertSQLState("3B502", se);
} else if (usingDerbyNetClient()) {
assertSQLState("XJ097", se);
}
}
con.commit();
con2.commit();
}
/**
* Helper method which drops a table if it exists. Nothing happens if
* the table doesn't exist.
*
* @param c the connection to use
* @param table the table to drop
* @throws SQLException if an unexpected database error occurs
*/
static void dropTable(Connection c, String table) throws SQLException {
// Create a savepoint that we can roll back to if drop table fails.
// This is not needed by Derby, but some databases (e.g., PostgreSQL)
// don't allow more operations in a transaction if a statement fails,
// and we want to be able to run these tests against other databases
// than Derby.
Savepoint sp = c.setSavepoint();
Statement stmt = c.createStatement();
try {
stmt.executeUpdate("DROP TABLE " + table);
} catch (SQLException e) {
// OK to fail if table doesn't exist, roll back to savepoint
c.rollback(sp);
}
stmt.close();
c.releaseSavepoint(sp);
}
/**
* Inserts one row into a table with an auto-generated column while inside
* a savepoint unit, does a rollback, then gets keys after an insert
* into a table without an auto-generated column.
* Old master Test 13.
* Expected result: ResultSet has one row with a non-NULL key, and the
* key value should be the same before and after the rollback.
* @throws SQLException
*/
public void testGetKeyAfterSavepointRollback() throws SQLException
{
Connection conn = getConnection();
Statement s = createStatement();
Savepoint savepoint1 = conn.setSavepoint();
int expected=1;
s.execute("insert into t11_AutoGen(c11) values(99)",
Statement.RETURN_GENERATED_KEYS);
int keyval = getKeyValue (s.getGeneratedKeys());
assertEquals("Key value before rollback", expected, keyval);
conn.rollback(savepoint1);
s.execute("insert into t21_noAutoGen values(39, 'true')",
Statement.RETURN_GENERATED_KEYS);
keyval = getKeyValue (s.getGeneratedKeys());
assertEquals("Key value after rollback", expected, keyval);
s.close();
}
/** Test 18 */
public void testNoNestedSavepointsInsideJdbcSavepoint() throws SQLException {
Connection con = getConnection();
Savepoint savepoint1 = con.setSavepoint();
Statement s = getConnection().createStatement();
// Following SQL savepoint will fail because we are trying to nest it
// inside JDBC savepoint
try {
s.executeUpdate("SAVEPOINT s1 ON ROLLBACK RETAIN LOCKS ON ROLLBACK"
+ " RETAIN CURSORS");
fail("FAIL 18 shouldn't be able set SQL savepoint nested inside "
+ "JDBC savepoints");
} catch (SQLException se) {
// Expected exception.
assertSQLState("3B002", se);
}
// rollback the JDBC savepoint. Now since there are no user defined
// savepoints, we can define SQL savepoint
con.releaseSavepoint(savepoint1);
s.executeUpdate("SAVEPOINT s1 ON ROLLBACK RETAIN LOCKS ON "
+ "ROLLBACK RETAIN CURSORS");
con.rollback();
}
/**
* Test 13 shouldn't be able to use a savepoint from earlier transaction
* after setting autocommit on and off
*/
public void testSavepointFromEarlierTransactionAfterToggleAutocommit()
throws SQLException {
Connection con = getConnection();
Savepoint savepoint1 = con.setSavepoint("MyName");
con.setAutoCommit(true);
con.setAutoCommit(false);
Savepoint savepoint2 = con.setSavepoint("MyName1");
try {// shouldn't be able to use savepoint from earlier tranasaction
// after setting autocommit on and off
con.releaseSavepoint(savepoint1);
fail("FAIL 13 shouldn't be able to use a savepoint from earlier "
+ "transaction after setting autocommit on and off");
} catch (SQLException se) {
// Expected exception.
assertSQLState("3B001", se);
}
con.releaseSavepoint(savepoint2);
con.rollback();
}
/** Test 15 Check savepoints in batch */
public void testSavepointsInBatch() throws SQLException {
Connection con = getConnection();
Statement s = createStatement();
s.execute("delete from t1");
s.addBatch("insert into t1 values(1,1)");
s.addBatch("insert into t1 values(2,2)");
Savepoint savepoint1 = con.setSavepoint();
s.addBatch("insert into t1 values(3,3)");
s.executeBatch();
con.rollback(savepoint1);
assertTableRowCount("T1", 0);
con.rollback();
}
/**
* Test 10 test savepoint name case sensitivity
*/
public void testNameCaseSensitivity() throws SQLException {
Connection con = getConnection();
Savepoint savepoint1 = con.setSavepoint("MyName");
String savepointName = savepoint1.getSavepointName();
assertEquals(savepointName, "MyName");
con.rollback();
}
public static void doConnectionSetSavepointUnnamed() throws Throwable
{
Connection conn = DriverManager.getConnection("jdbc:default:connection");
Savepoint s1 = conn.setSavepoint();
Statement s = conn.createStatement();
s.executeUpdate("insert into t2 values(1)");
conn.rollback(s1);
}
/**
* Test40 - We internally generate a unique name for unnamed savepoints. If
* a named savepoint uses the currently used internal savepoint name, we
* won't get an exception thrown for it because we prepend external saves
* with "e." to avoid name conflicts.
*/
public void xtestNoConflictWithGeneratedName() throws SQLException {
Connection con = getConnection();
con.setSavepoint();
con.setSavepoint("i.SAVEPT0");
con.rollback();
}
public static void doConnectionSetSavepointUnnamed() throws Throwable
{
Connection conn = DriverManager.getConnection("jdbc:default:connection");
Savepoint s1 = conn.setSavepoint();
Statement s = conn.createStatement();
s.executeUpdate("insert into t2 values(1)");
conn.rollback(s1);
}
/**使用一个全新的名称创建一个保存点。*/
@Override
public Savepoint createSavepoint() throws SQLException {
Connection conn = this.checkConn(this.getConnection());
this.savepointCounter++;
return conn.setSavepoint(ConnectionHolder.SAVEPOINT_NAME_PREFIX + this.savepointCounter);
}
public Savepoint setSavepoint() throws SQLException {
_txn = true;
StackElement st = new StackElement(START_TXN, null);
_stack.push(st);
final Connection conn = getConnection();
final Savepoint sp = conn.setSavepoint();
st.ref = sp;
return sp;
}
/**
* Test42 - Rollback on a connection will release all the savepoints created
* for that transaction
*/
public void xtestRollbackWillReleaseActiveSavepoints() throws SQLException {
Connection con = getConnection();
Savepoint savepoint1 = con.setSavepoint();
con.rollback();
try {
con.rollback(savepoint1);
fail("FAIL 42 release of rolled back savepoint");
} catch (SQLException se) {
// Expected exception.
assertSQLState("3B001", se);
}
}
/**
* Test 12 releasing a savepoint multiple times - should not work
*/
public void testReleaseMultipleTimes() throws SQLException {
Connection con = getConnection();
Savepoint savepoint1 = con.setSavepoint("MyName");
con.releaseSavepoint(savepoint1);
try {
con.releaseSavepoint(savepoint1);
fail("FAIL 12 releasing a savepoint multiple times should fail");
} catch (SQLException se) {
// Expected exception.
assertSQLState("3B001", se);
}
con.rollback();
}
/**
* Test2 - After releasing a savepoint, should be able to reuse it.
*/
public void testReusingSavepoints() throws SQLException {
Connection con = getConnection();
Savepoint savepoint1 = con.setSavepoint("s1");
con.releaseSavepoint(savepoint1);
con.setSavepoint("s1");
con.rollback();
}
/**
* Test3 - Named savepoints can't pass null for name
*/
public void testNullName() throws SQLException {
Connection con = getConnection();
try {
con.setSavepoint(null);
fail("FAIL 3 Null savepoint");
} catch (SQLException se) {
// Expected exception.
assertSQLState("XJ011", se);
}
con.rollback();
}
/**
* test 6a - create a savepoint release it and then create another with the
* same name. and release the first one
*/
public void testReleaseReleasedSavepoint() throws SQLException {
Connection con = getConnection();
Savepoint savepoint1 = con.setSavepoint("s1");
con.releaseSavepoint(savepoint1);
// The following savepoint was earlier named s1. Changed it to s2 while
// working on DRDA support
// for savepoints. The reason for that is as follows
// The client translates all savepoint jdbc calls to equivalent sql and
// hence
// if the 2 savepoints in
// a transaction are named the same, then the release savepoint below
// will get converted to
// RELEASE TO SAVEPOINT s1 and that succeeds because there is a valid
// savepoint named s1.
con.setSavepoint("s2");
Statement s = createStatement();
s.executeUpdate("INSERT INTO T1 VALUES(2,1)");
try {
con.releaseSavepoint(savepoint1);
fail("FAIL 6a - releasing a released savepoint did not raise error");
} catch (SQLException se) {
// Expected exception.
assertSQLState("3B001", se);
}
con.commit();
}