- 在实际的业务开发中,有些业务操作要多次访问数据库。一个业务要发送多条SQL语句给数据库执行。需要将多次访问数据库的操作视为一个整体来执行,要么所有的SQL语句全部执行成功。如果其中有一条SQL语句失败,就进行事务的回滚,所有的SQL语句全部执行失败。
- MySQL自动默认提交事物,当我们执行的一条语句都是一个事物,执行完语句自动提交事物。
- 在MySQL中提交事物的方式分为两种:自动提交和手动提交
- 开启事物之后所有的操作都会临时保存到事物操作日志,事物日志只有在得到commit命令之后才会将数据同步到表中,其他的任何情况都会清空事物日志(rollback,断开连接等);
事物的提交语句
事物的执行流程
手动提交事物
- 开启事物:START TRANSACTION;
- 执行sql语句
- 在控制台输入commit提交事物;
自动提交事物
通过修改mysql全局变量"autocommit"可以操作是否自动开启事物
- 在控制台输入
show variables like '%commit%';
来查看是否开启自动提交事物; - 设置autocommit的状态
set autocommit = 1;
,0为关闭,1为开启;
回滚点
- 在某些成功的操作完成之后,后续的操作有可能成功有可能失败,但是不管成功还是失败,前面操作都已经成功,可以在当前成功的位置设置一个回滚点。可以供后续失败操作返回到该位置,而不是返回所有操作,这个点称之为回滚点。
- 设置回滚点的语法:savepoint 回滚点的名字;
- 回到回滚点的语法:rollback to 回滚点的名字;
事物的4大特性
事物的隔离级别
事务在操作时的理想状态:多个事务之间互不影响,如果隔离级别设置不当就可能引发并发访问问题。
- 查询事物隔离级别:
show variables like '%isolation%';
-- 或
select @@tx_isolation;
- 设置事物隔离级别
set global transaction isolation level 级别字符串;
-- 如:
set global transaction isolation level read uncommitted;
事物的使用
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/*
JDBC 的 事务管理操作
JDBC
java 连接 数据库 技术
原生JDBC
六步
1: 注册驱动
2:获取连接对象
3:创建语句执行平台
4:执行sql
5: 处理结果(集)
6:释放资源
使用 JDBC 完成事务管理
如果在 操作 事务的过程中
遇到了异常
回滚
转账事务 sql update
Statement Connection
*/
public class JDBCTranDemo {
public static void main(String[] args) {
// 连接对象
Connection conn = null;
// 语句执行平台
Statement state = null;
try{
//1: 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2:获取连接对象
conn = DriverManager
.getConnection("jdbc:mysql://IP:端口号/数据库名", "账号",
"密码");
//开启事务
conn.setAutoCommit(false);
//3: 创建语句执行平台
state = conn.createStatement();
//4:执行sql
//转钱 jack-1000
state.executeUpdate("update account set money=money-1000 where name='jack'");
// 假设停电了
System.out.println(1/0);
state.executeUpdate("update account set money=money+1000 where name='rose'");
// 成功 提交
conn.commit();
System.out.println("转账成功");
}catch(Exception e){
//如果转账的过程中 出现了异常 那么进行回滚操作
if(conn!=null){
try {
conn.rollback();
System.out.println("转账失败");
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}finally {
//释放资源
if(state!=null){
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}