论坛首页 Java企业应用论坛

讨论一下JDBC中setAutoCommit的问题

浏览 11474 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-04  
环境:JDK7,mysql5.0.18,INNODB方式:
问题:JDBC中设置了连接为不自动提交(.setAutoCommit(false)),程序中不调用conn.commit();但是数据依然插入数据了?搞不明白:
程序里设置了conn.setAutoCommit(false):
1、存储过程中没有显示执行commit; 也可以插入数据可以
2、直接在java中执行一条insert SQL语句,依然能够插入到数据
3、执行insert语句,不commit,rollback也无效

难道还要在数据库与手动设置一下什么变量?比如取消自动提交模式(我记得oracle和mysql默认是打开自动提交的)吗?

测试代码如下:
存储过程:
DROP PROCEDURE IF EXISTS p_test;

CREATE PROCEDURE p_test (in userName VARCHAR(20))
BEGIN
  INSERT INTO TEST (user_name) VALUES (userName);
  select * from test;
END


java 测试程序:

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class CallableStat {
	private Connection getConn() {
		Connection conn = null;
		try {
			Class.forName("org.gjt.mm.mysql.Driver").newInstance();
			conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mysql?useUnicode=true&characterEncoding=GB2312", "root", "root");
		} catch (Exception e) {
			e.printStackTrace();
			// TODO: handle exception
		}
		return conn;
	}

	public void testC() {
		Connection conn = getConn();
		ResultSet rs = null;
		CallableStatement cs = null;
		String a = null;
		try {
			conn.setAutoCommit(false); // 取消自动提交
			CallableStatement cStmt = null;
			// for (int i = 0; i < 3; i++) {
			// cStmt = conn.prepareCall("{call p_test('kevin" + i + "')}");
			// rs = cStmt.executeQuery();
			// }

			for (int i = 0; i < 3; i++) {
				cStmt = conn.prepareCall("{call p_test(?)}");

				cStmt.setString(1, "Kevin" + i);
				cStmt.executeUpdate();
			}
			// cStmt.registerOutParameter(2, Types.ARRAY);
			// 执行存储过程
			// 如果有查询语句的话,此执行过程会返回结果集,在此处理结果集里面的东西
			// System.out.println("Data from table:");
			// int i = 1;
			// while (rs.next()) {
			// int id = rs.getInt(0);
			// String name = rs.getString(1);
			// System.out.println("record " + i);
			// i++;
			// System.out.println("Id=" + id + "\t" + "name=" + name);
			// }

		} catch (Exception e) {
			System.out.println("Error1 MSG: " + e.getMessage());
			e.printStackTrace();
		} finally {
			try {
				conn.close();
			} catch (Exception ex) {
				System.out.println("Error2 MSG: " + ex.getMessage());
				ex.printStackTrace();
			}
		}
	}

	public void testInsert() {
		Connection conn = getConn();
		ResultSet rs = null;
		CallableStatement cs = null;
		String a = null;
		try {
			conn.setAutoCommit(false); // 取消自动提交
			Statement stmt = null;

			stmt = conn.createStatement();
			stmt.execute("insert into test(user_name) values ('kevin2')"); //执行后数据库就有记录了
			System.out.println("休眠20秒钟");
			Thread.sleep(10000L);
			System.out.println("休眠结束,执行完毕;");
			conn.rollback(); //也无法

		} catch (Exception e) {
			System.out.println("Error1 MSG: " + e.getMessage());
			e.printStackTrace();
		} finally {
			try {
				conn.close();
			} catch (Exception ex) {
				System.out.println("Error2 MSG: " + ex.getMessage());
				ex.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		// new CallableStat().testC();
		new CallableStat().testInsert();
	}
}


以上测试程序在我的环境中,数据都插入了:
1、调用陈村过程后,没有执行commit操作,数据也插入到数据库了;
2、调用insert语句后,没有执行commit操作,数据也插入到数据库了;
3、执行insert后,没有执行commit操作,执行rollback也无效;

   发表时间:2012-12-04  
我这里没问题, 建议你check下org.gjt.mm.mysql.Driver
0 请登录后投票
   发表时间:2012-12-04  
cectsky 写道
我这里没问题, 建议你check下org.gjt.mm.mysql.Driver


这么check,我换了4个mysql的驱动来测试,都一样,从官网下载的,测试结果都一样!
”com.mysql.jdbc.Driver“ 和 ”org.gjt.mm.mysql.Driver“两中方是,都一样。
4个驱动都是从mysql的官网上下载的:

  • 大小: 15.6 KB
0 请登录后投票
   发表时间:2012-12-04  
mysql的配置文件中设置
autocommit =0
试试
0 请登录后投票
   发表时间:2012-12-04  
stmt.executeQuery("SET AUTOCOMMIT=0"); 也木有用。
呵呵、已经知道原因了,
NND,安装数据库时已经选了InnoDB引擎了,可是建表的时候,既然默认是MyISAM模式,而该模式是不支持事务的,所以不管是设置setAutoCommit(false)还是‘SET AUTOCOMMIT=0’都没有用!

修改表的类型为InnoDB就可以了
0 请登录后投票
   发表时间:2012-12-05  
ITFarmer 写道
stmt.executeQuery("SET AUTOCOMMIT=0"); 也木有用。
呵呵、已经知道原因了,
NND,安装数据库时已经选了InnoDB引擎了,可是建表的时候,既然默认是MyISAM模式,而该模式是不支持事务的,所以不管是设置setAutoCommit(false)还是‘SET AUTOCOMMIT=0’都没有用!

修改表的类型为InnoDB就可以了


楼主威武,学习了
0 请登录后投票
   发表时间:2012-12-05  
我用工具建的表,默认都是InnoDB类型额。。。
0 请登录后投票
   发表时间:2012-12-06  
sweat89 写道
我用工具建的表,默认都是InnoDB类型额。。。

偶也没太注意,一般项目都是用pd来建模,默认是InnoDB,但是因为这个只是个demo,就收工写代码了,没有显示指定存储引擎为InnoBD,结果默认就成了MyISAM模式了。

找了N久时间
0 请登录后投票
   发表时间:2012-12-07  
ITFarmer 写道
stmt.executeQuery("SET AUTOCOMMIT=0"); 也木有用。
呵呵、已经知道原因了,
NND,安装数据库时已经选了InnoDB引擎了,可是建表的时候,既然默认是MyISAM模式,而该模式是不支持事务的,所以不管是设置setAutoCommit(false)还是‘SET AUTOCOMMIT=0’都没有用!

修改表的类型为InnoDB就可以了

一个不支持事务的数据库模式,有什么存在的意义呢?
0 请登录后投票
   发表时间:2012-12-07  
还有这种事儿,学习了!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics