1、基本概念
事务是数据库中的概念,具有ACID特性。这里只给出一个很直白的描述:在数据库操作中,将几种动作看成不可分割的整体,要么一起生效,要么全部失效,不能有部分生效而部分失效的情况。
一般情况下,一条SQL语句的执行即是一个事务,要么成功要么失败。如果成功,自动提交,对数据库的改变会是永久的;如果失败了,自动回滚,不会对原有的数据造成影响。这是最基础的“事务机制”。一条SQL语句也可以写的很复杂,里面包含大量的动作。
二般情况下,业务很复杂,需要多条SQL语句的配合才能实现。这时,如果其中一条失败了,在业务逻辑上,我们需要其他的SQL也不能生效。但是数据库只能保证单条SQL语句的这种特性,多条SQL时,我们需要将它们“打包”伪装成一条,从而实现单条SQL类似的效果,这就是事务了。
2、JDBC的MySQL示例
在Java程序中连接MySQL数据库需要一个驱动包:mysql-connector-java-5.1.38.jar
然后,在代码中获取一个数据库的连接:
接着,就可以测试事务了:
这里的关键就是con.setAutoCommit(false),因为在默认情况下,con的autoCommit属性值是true,这时候,stmt的每次execute都是一个独立的执行单元,数据库会自动帮它提交或回滚;但是如果想让两个execute绑定到一起成为一个执行单元,就必须先setAutoCommit(false)。当然,这时数据库不会在帮它们自动提交或回滚了,所以你自己必须加入相应的代码,即con.commit()和con.rollback()
最后命令行编译:javac Xx.java 这会生成Xx.class
然后在命令行执行:java Xx
但是一般会遇到如下报错:
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
所以此时需要加上驱动jar包的路径:
java -cp .:/path/mysql-connector-java-5.1.38.jar Xx
cp选项用来指定classpath路径;Linux下多个路径需要用冒号分隔;必须指定被执行类所在路径,如果已在类的目录,可以用点号简写当前路径。
事务是数据库中的概念,具有ACID特性。这里只给出一个很直白的描述:在数据库操作中,将几种动作看成不可分割的整体,要么一起生效,要么全部失效,不能有部分生效而部分失效的情况。
一般情况下,一条SQL语句的执行即是一个事务,要么成功要么失败。如果成功,自动提交,对数据库的改变会是永久的;如果失败了,自动回滚,不会对原有的数据造成影响。这是最基础的“事务机制”。一条SQL语句也可以写的很复杂,里面包含大量的动作。
二般情况下,业务很复杂,需要多条SQL语句的配合才能实现。这时,如果其中一条失败了,在业务逻辑上,我们需要其他的SQL也不能生效。但是数据库只能保证单条SQL语句的这种特性,多条SQL时,我们需要将它们“打包”伪装成一条,从而实现单条SQL类似的效果,这就是事务了。
2、JDBC的MySQL示例
在Java程序中连接MySQL数据库需要一个驱动包:mysql-connector-java-5.1.38.jar
然后,在代码中获取一个数据库的连接:
public static Connection getConnection() {
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/timeRecord";
String username = "m";
String password = "123456";
con = DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException) {
ce.printStackTrace();//驱动没找到
} catch (SQLException se) {
se.printStackTrace();//连接数据库失败
}
return con;
}
这里要注意几点:跟数据库连接相关的类在java.sql包中,所以需要导入java.sql.*;MySQL的监听端口号是3306;由于这里加载驱动的方式是Class.forName,然后驱动路径是以字符串的形式给出的,所以编译时不需要import驱动的包,但是在运行时却必须给出jar包所在的路径。
接着,就可以测试事务了:
public static void main(String args[]) {
Connection con = null;
Statement stmt = null;
try {
con = getConnection();
con.setAutoCommit(false);
stmt = con.createStatement();
stmt.execute("insert test values(2)");
stmt.execute("insert test values(3)");
con.commit();
} catch(SQLException se) {
try {
con.rollback();
stmt.close();
con.close();
} catch(Exception e) {
}
se.printStackTrace();//SQL语句执行失败
}
}
这里的关键就是con.setAutoCommit(false),因为在默认情况下,con的autoCommit属性值是true,这时候,stmt的每次execute都是一个独立的执行单元,数据库会自动帮它提交或回滚;但是如果想让两个execute绑定到一起成为一个执行单元,就必须先setAutoCommit(false)。当然,这时数据库不会在帮它们自动提交或回滚了,所以你自己必须加入相应的代码,即con.commit()和con.rollback()
最后命令行编译:javac Xx.java 这会生成Xx.class
然后在命令行执行:java Xx
但是一般会遇到如下报错:
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
所以此时需要加上驱动jar包的路径:
java -cp .:/path/mysql-connector-java-5.1.38.jar Xx
cp选项用来指定classpath路径;Linux下多个路径需要用冒号分隔;必须指定被执行类所在路径,如果已在类的目录,可以用点号简写当前路径。