您的位置:首页 > 产品设计 > UI/UE

JDBC的autoCommit为true时,其事务管理测试

2015-12-04 18:32 519 查看
前述:事务做为数据库操作特别重要的一方面,不做过多赘述。spring框架使用太久后总忽略一些比较原始的东西,老项目中又使用了这些,看到一些东西总感觉迷惑。比如当使用jdbc调用一个存储过程,该存储过程又有很多子sql语句时,若存储过程出现异常,执行结果如何?猜测会整个回退,但是autoCommit不是自动提交吗?

(jdbc的连接connection默认自动提交autoCommit为ture)

下面就开启探究之旅。。。。。。

测试/验证思路:

1.测试连接获取到之后,进行连续多个CRUD操作,查看操作后期异常和全程无异常的情况。

2.测试连接获取到之后,进行调用存储过程,存储过程中多个CRUD操作(存储过程中无commit语句),查看操作后期异常和全程无异常的情况。

3.测试连接获取到之后,进行调用存储过程,存储过程中多个CRUD操作(存储过程中无commit语句),查看操作后期异常和全程无异常的情况。

此处只为测试,忽略代码是否优美

首先建立测试表,注意两张表的字段长度是不一样的。

create table TEST_LEON_T1(name varchar2(20));
create table TEST_LEON_T2(name varchar2(5));


java代码如下:

public class Test {
public Connection conn ;
public static void main(String[] args) {
String name = "abc";
testInsert(name);
}
//测试连续插入
public static void testInsert(String name){
Test test = new Test();
try {
test.initConnction();
String sql = "insert into TEST_LEON_T1(name) values(?)";
PreparedStatement ps = test.conn.prepareStatement(sql);
ps.setString(1, name);
ps.execute();
String sql2 = "insert into TEST_LEON_T2(name) values(?)";
PreparedStatement ps2 = test.conn.prepareStatement(sql2);
ps2.setString(1, name);
ps2.execute();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
test.close();
}
}
//测试调用存过
public static void testProcedure(String name){
Test test = new Test();
try {
test.initConnction();
String sql = "{call TEST_LEON_P1(?)}";
CallableStatement cs = test.conn.prepareCall(sql);
cs.setString("name", name);
cs.execute();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
test.close();
}
}
public void initConnction() throws ClassNotFoundException, SQLException{
Class.forName("oracle.jdbc.driver.OracleDriver");
String user = "leon";
String pwd = "leon";
String url = "jdbc:oracle:thin:@127.0.0.1:1522:leon";
conn = DriverManager.getConnection(url,user,pwd);
}
public void close(){
if(conn!=null)
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}


1. main调用testInsert(“leon”)执行,结果为全部插入。

2. main调用testInsert(“zhangsan”)执行,结果表TEST_LEON_T1数据插入,表TEST_LEON_T2数据无插入。

3. 调整testInsert代码,在finally中加入以下代码继续执行以上两步,发现结果没有变化,第二个测试中TEST_LEON_T1数据仍然插入进去了

try {
test.conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}


结论:

JDBC执行sql默认提交,每一个sql语句执行后提交一次。(下面通过存储过程的调用进行验证)

存过无commit

create or replace PROCEDURE TEST_LEON_P1(name in varchar2) as
begin
insert into TEST_LEON_T1 (name) values (name);
insert into TEST_LEON_T2 (name) values (name);
end;


1. main调用testProcedure(“leon”)执行,结果为全部插入。

2. main调用testProcedure(“zhangsan”)执行,结果两表都没有数据插入。

3. 再调整一下存储过程,在两条sql语句中加入commit,main调用testProcedure(“zhangsan”)执行,结果表TEST_LEON_T1数据插入,表TEST_LEON_T2数据无插入。

这个结果证明:

jdbc执行sql时,连接默认设置autoCommit为true,即默认自动提交,自动提交意味着每执行一条sql进行commit一次,commit提交的最小单位为一条sql语句,无论是CRUD操作还是调用存储过程,都算作一个基本提交单元。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: