Mysql中的事务管理
mysql 的事务默认自动打开,自动提交。
每一条sql就是一个单独的事务,所以不需要 事务开启、事务回滚、事务提交。
Mysql中事务的使用:
start transaction; --- 开启事务。以后的sql都在一个事务中。更改的内容不会自动提交。
rollback; --- 回滚事务,都失败的情况。事务结束,全部失败,数据恢复到事务未开启之前的状态。
commit; --- 提交事务,都成功的情况。事务结束,全部成功。
【示例:演示事务回滚】
步骤一:创建财务表account,表中有列名name和salary,并且插入初始数据 a 和 b各自1000元
#创建account表
createtable account(
name varchar(20),
salary double
);
#插入初始数据:a 和 b 各自1000元
insertinto account values('a',1000);
insertinto account values('b',1000);
步骤二:开启事务后,a向b开始转账,然后回滚事务
#开启事务
starttransaction;
#执行一组sql的操作
updateaccount set salary = salary - 100 where name = 'a';
updateaccount set salary = salary + 100 where name = 'b';
#查询结果(a:900 b:1100)
select *from account
#操作 事务回滚 一切回到开启事务之前的的状态
rollback
#再次查询结果 【a:1000,b:1000】
select *from t_account t
【示例2:演示事务提交】
#开启事务
starttransaction
#执行一组sql的操作
updateaccount set salary = salary - 100 where name = 'a';
updateaccount set salary = salary + 100 where name = 'b';
#查询结果【a:900 b:1100】
select *from account
#执行事务回滚中的提交命令 (与开启事务对应)(类似确认提交)
commit
#再次查询结果【a:900 b:1100】
select *from account
【JDBC中的事务管理】
package com.flying.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.junit.Test;
public class ShiwuTest {
//第一次:正常测试【结果a-100 b+100】
@Test
public void shiwu(){
Connection con =null;
PreparedStatement pt=null;
try {
con = JdbcUtils.getConnection();
String sql1="update account set gongzi=gongzi-100 where name='a'";
String sql2="update account set gongzi=gongzi+100 where name='b'";
pt = con.prepareStatement(sql1);
pt.executeUpdate();
pt=con.prepareStatement(sql2);
pt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils.release(con, pt);
}
}
//第二次:异常测试 【结果a少了100,b未变化】
@Test
public void shiwu2(){
Connection con =null;
PreparedStatement pt=null;
try {
con = JdbcUtils.getConnection();
String sql1="update account set gongzi=gongzi-100 where name='a'";
String sql2="update account set gongzi=gongzi+100 where name='b'";
pt = con.prepareStatement(sql1);
pt.executeUpdate();
// 人为添加 发生异常(注意此时上句已执行,下句还未执行)
int x = 1 / 0;
pt = con.prepareStatement(sql2);
pt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.release(con, pt);
}
}
//第三次:开启事务 异常测试 【示例3:演示事务回滚点】
@Test
public void shiwu3(){
Connection con =null;
PreparedStatement pt=null;
try {
con = JdbcUtils.getConnection();
//开启事务必须在建立连接后立马开启才有用,执行sql语句后就要提交事务
con.setAutoCommit(false);
String sql1="update account set gongzi=gongzi-100 where name='a'";
String sql2="update account set gongzi=gongzi+100 where name='b'";
pt = con.prepareStatement(sql1);
pt.executeUpdate();
// 人为添加 发生异常(注意此时上句已执行,下句还未执行)
int x = 1 / 0;
pt = con.prepareStatement(sql2);
pt.executeUpdate();
//在执行以上代码后才可以提交事务,要放在执行所有sql语句的最后
con.commit();
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.release(con, pt);
}
}
}
Jdbc中事务的使用
1、 开启事务:connection.setAutoCommit(false)
2、 执行一组sql语句
3、 提交事务:connection.commit()/回滚事务:connection.rollback();
注意点:
1、开启事务 conn.setAutoCommit(false)必须在建立connection之后设置。
2、抓异常时,最好选得大一些。因为 int x = 1/0报的是算术异常,不在sql异常范围内,所以最好改成Exception。
开启事务:con.setAutoCommit(false);
参数为false,表示禁用自动提交模式,相当于strart transaction -- 开启事务。
参数为true,表示自动提交。默认就是true。 -- 一条sql语句就是一个事务。
事务回滚
注意:con.rollback() 应该只在开启事务时使用,即con.setAutoCommit(false); 时才有效。
相当于rollback(), 回滚事务。 表示事务结束,取消当前事务的所有更改。
事务提交
注意:con.commit() 应该只在开启事务时使用,即conn.setAutoCommit(false); 时才有效。
【设置回滚点】
注意点:
1、设置回滚点,必须事务开启之后。
2、事务回滚,需要设置一个回滚点。
3、事务回滚到回滚点之后,还需要提交事务,才能将回滚点之前的数据持久化到数据库。