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); 时才有效。

相当于commit() 提交事务。表示事务结束,更改有效。


【设置回滚点】

注意点:

1、设置回滚点,必须事务开启之后。

2、事务回滚,需要设置一个回滚点。

3、事务回滚到回滚点之后,还需要提交事务,才能将回滚点之前的数据持久化到数据库。