事务在JDBC中十分重要,不支持事务会出现许多问题。下面举两个例子,分别是不使用事务和使用事务的情况。
1.不使用事务的情况
这里举一个例子:
package jdbc7;
import java.sql.*;
public class test1 {
public static void main(String[] args) {
Connection c = null;
PreparedStatement ps = null;
try{
Class.forName("com.mysql.jdbc.Driver");
c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8","root","admin");
String sql = "update hero set hp = hp +1 where id = 22";
String sql2 = "updata hero set hp = hp -1 where id = 22";
ps = c.prepareStatement(sql);
ps.execute();
ps = c.prepareStatement(sql2);
ps.execute();
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch (SQLException e) {
e.printStackTrace();
}finally{
if(ps != null) {
try {
ps.close();
}catch(Exception e) {
e.printStackTrace();
}
ps = null;
}
if(c != null) {
try {
c.close();
}catch(Exception e) {
e.printStackTrace();
}
c = null;
}
}
}
}
上述程序是没有使用事务的情况,假设业务操作是:加血,减血各做一次,结束后,英雄的血量不变。而减血的SQL不小心写错写成了 updata(而非update),那么最后结果是血量增加了,而非期望的不变。
执行前表中第22行:
执行之后:
和期望的血量不变产生差异,那么如何来避免这种情况的发生呢?这里就需要使用事务
2.使用事务
同样是刚才的程序,也是这些加血见血操作,也是把update写错,产生的结果却截然不同
package jdbc7;
import java.sql.*;
public class test2 {
public static void main(String[] args) {
Connection c = null;
Statement s = null;
try {
Class.forName("com.mysql.jdbc.Driver");
c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8\",\"root\",\"admin");
s = c.createStatement();
c.setAutoCommit(false);
String sql1 = "update hero set hp = hp +1 where id = 22";
s.execute(sql1);
String sql2 = "updata hero set hp = hp -1 where id = 22";
s.execute(sql2);
c.commit();
}catch(ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
if(s != null) {
try {
s.close();
}catch(Exception e) {
e.printStackTrace();
}
s = null;
}
if(c != null) {
try {
c.close();
}catch(Exception e) {
e.printStackTrace();
}
c = null;
}
}
}
}
运行结果:
血量没有发生变化,符合预期。
总结:
在事务中的多个操作,要么都成功,要么都失败
通过 c.setAutoCommit(false);关闭自动提交
使用 c.commit();进行手动提交。
所以,虽然第一条SQL语句是可以执行的,但是第二条SQL语句有错误,其结果就是两条SQL语句都没有被提交。 除非两条SQL语句都是正确的。