1.事务的概念和MySQL事务支持
- 事务是由一步或者几步数据库操作序列组成的逻辑执行单元,这些单元中的操作要么全部执行,要么全部放弃;
- 事务是程序的一部分,事务包括以下特性:
- 原子性:事务是应用中的最小单位;
- 一致性:事务的执行结果,必须要让数据库从一个状态转换到另一个状态;
- 隔离性:各个事务之间不互相干扰;
- 持续性:事务一旦提交,对数据所做的任何改变都要存储到数据库中;
2.JDBC的事务支持
- 数据库事务默认关闭,在jdbc中,开启事务的方法为:
//关闭自动提交,开启事务
conn.setAutoCommit(false);
- 在完成了SQL语句的编写时,在程序中添加:
stmt.executeUpdate(...);
stmt.executeUpdate(...);
stmt.executeUpdate(...);
... //不会执行SQL语句,等待提交事务
conn.commit(); //提交事务;
//如果任意一条SQL语句执行失败,回滚事务:
conn.rollback(); //回到执行之前的状态;
- 展示一个自动回滚操作的程序:
import java.sql.*;
import java.io.*;
import java.util.*;
public class TransactionTest
{
private String driver;
private String url;
private String user;
private String pass;
public void initParam(String paramFile) throws Exception
{
//初始化SQL登录参数;
var props = new Properties();
props.load(new FileInputStream(paramFile));
driver = props.getProperty("driver");
url = props.getProperty("url");
user = props.getProperty("user");
pass = props.getProperty("pass");
}
public void insertInTransaction(String[] sqls) throws Exception
{
//加载驱动
Class.forName(driver);
try (
Connection conn = DriverManager.getConnection(url, user, pass))
{
//启动事务
conn.setAutoCommit(false);
try (
//创建执行对象stmt
Statement stmt = conn.createStatement())
{
for (String sql : sqls)
{
stmt.executeUpdate(sql);
}
}
//提交事务
conn.commit();
}
}
public static void main(String[] args) throws Exception
{
var tt = new TransactionTest();
tt.initParam("mysql.ini");
var sqls = new String[]{
"insert into student_table values(null, 'aaa', 1)",
"insert into student_table values(null, 'bbb', 1)",
"insert into student_table values(null, 'ccc', 1)",
//出错的话程序会自动回滚;
"insert into student_table values(null, 'ccc', 5)"
};
tt.insertInTransaction(sqls);
}
}
3.使用批量更新
- 使用批量更新时,多条SQL语句将被作为一批操作被同时收集并提交;
import java.sql.*;
import java.io.*;
import java.util.*;
public class BatchTest
{
private String driver;
private String url;
private String user;
private String pass;
public void initParam(String paramFile) throws Exception
{
var props = new Properties();
props.load(new FileInputStream(paramFile));
driver = props.getProperty("driver");
url = props.getProperty("url");
user = props.getProperty("user");
pass = props.getProperty("pass");
}
public void insertBatch(String[] sqls) throws Exception
{
Class.forName(driver);
try (
Connection conn = DriverManager.getConnection(url, user, pass))
{
conn.setAutoCommit(false);
//保存当前的自动提交模式
boolean autoCommit = conn.getAutoCommit();
//关闭自动提交
conn.setAutoCommit(false);
try (
Statement stmt = conn.createStatement())
{
for (var sql : sqls)
{
//将sql填入到批处理对象中
stmt.addBatch(sql);
}
//执行批处理命令
stmt.executeLargeBatch();
//提交修改
conn.commit();
//恢复原有的自动提交模式
conn.setAutoCommit(autoCommit);
}
//提交事务;
conn.commit();
}
}
public static void main(String[] args) throws Exception
{
var tt = new TransactionTest();
tt.initParam("mysql.ini");
var sqls = new String[]{
"insert into student_table values(null, 'aaa', 1)",
"insert into student_table values(null, 'bbb', 1)",
"insert into student_table values(null, 'ccc', 1)",
};
tt.insertInTransaction(sqls);
}
}