事务

事务

1.事务的概念

•事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部不成功。
•例如:A——B转帐,对应于如下两条sql语句

  update account set money=money-100 wherename=‘a’;

  update account set money=money+100 wherename=‘b’;

2、TPL

事务(Transaction)处理语言

数据库有可能是自动提交事务的(MySQL默认就是自动提交事务的),每一条语句都是单独的事务。

start transaction:开启事务

commit:提交事务。永久的存储到硬盘上

rollback:回滚事务。回到最开始的地方

3、JDBC控制事务

当Jdbc程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。
若想关闭这种默认提交方式,让多条SQL在一个事务中执行,可使用下列语句:
JDBC控制事务语句:
•Connection.setAutoCommit(false);start transaction
•Connection.rollback();  rollback
•Connection.commit();  commit
package com.hcx.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.junit.Test;

import com.hcx.utils.JdbcUtils;
演示事务
//CREATE TABLE bank
//(
//	id INT PRIMARY KEY, 
//	NAME VARCHAR(20) ,
//	money FLOAT 
//)
//
//INSERT INTO bank VALUES(1,"张无忌",10000) ;
//INSERT INTO bank VALUES(2,"令狐冲",1) ;
//
//SELECT * FROM bank ;

public class TransactionTest {

	//模拟执行张无忌给令狐冲转账5000
	@Test
	public void testTransaction() throws Exception {
		// 获得链接对象
		Connection conn = JdbcUtils.getConnection();
		PreparedStatement pstmt = conn.prepareStatement("update bank set money = money -? where id = ?") ;
		pstmt.setFloat(1, 5000) ;
		pstmt.setInt(2, 1) ;
		int n = pstmt.executeUpdate() ;
		System.out.println(n);
		
		System.out.println(10/0);
		
		PreparedStatement pstmt1 = conn.prepareStatement("update bank set money = money + ? where id = ?") ;
		pstmt1.setFloat(1, 5000) ;
		pstmt1.setInt(2, 2) ;
		int n1 = pstmt1.executeUpdate() ;
		System.out.println(n1);
		
		// 释放资源
		JdbcUtils.release(null, pstmt, conn);
		JdbcUtils.release(null, pstmt1, conn);
	}
	
	//采用事务处理转账失败的情况
	@Test
	public void testTransaction1() throws Exception {
		// 获得链接对象
		Connection conn = JdbcUtils.getConnection();
		
		PreparedStatement pstmt = null ;
		PreparedStatement pstmt1 = null ;
		//让数据库不要自动提交事务
		conn.setAutoCommit(false) ;
		try{
			pstmt = conn.prepareStatement("update bank set money = money -? where id = ?") ;
			pstmt.setFloat(1, 2000) ;
			pstmt.setInt(2, 1) ;
			int n = pstmt.executeUpdate() ;
			System.out.println(n);
			
			System.out.println(10/2);
			
			pstmt1 = conn.prepareStatement("update bank set money = money + ? where id = ?") ;
			pstmt1.setFloat(1, 2000) ;
			pstmt1.setInt(2, 2) ;
			int n1 = pstmt1.executeUpdate() ;
			System.out.println(n1);
			
			//手动进行提交,体现一致性
			conn.commit() ;
		}catch(Exception  e){
			//让事务进行回滚
			conn.rollback() ;
		}
		
		// 释放资源
		JdbcUtils.release(null, pstmt, conn);
		JdbcUtils.release(null, pstmt1, conn);
	}
}

4.事务的特性(ACID)

l 原子性( Atomicity
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 
l 一致性( Consistency
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
l 隔离性( Isolation
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
l 持久性( Durability
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

 

5.事务的隔离级别

l多个线程开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。

不考虑事务的隔离级别会导致什么问题?

1、脏读:指一个事务到读到另外一个事务中未提交的数据。

2、不可重复读:指一个事务读到另外一个事务执行update的语句的结果(已提交)

3、虚读:指一个事务读到另外一个事务执行的insert的语句的结果(已提交)

 

MySQL中支持的事务隔离级别:

READ UNCOMMITTED:脏读、不可重复读、虚读有可能发生。

READ COMMITTED:防止脏读的发生;不可重复读、虚读有可能发生。

REPEATABLE READ:防止脏读、不可重复读的发生;虚读有可能发生。(MySQL中默认)

SERIALIZABLE:防止脏读、不可重复读、虚读。

 

随着级别的增高,数据越安全,但效率越低。

 

MySQL中常用的命令:

查看当前的事务隔离级别:select@@tx_isolation;

更改当前的事务隔离级别:settransaction isolation level 四个级别; 

6.数据库的锁

共享锁

一个事务开启时,使用了共享锁,其他事务也可以设置共享锁。读数据是没有问题的。

select * from XXX lock in share mode;

排他锁

一个事务开启时,使用了排他锁,其他事务只有等待

update insert 等语句会自动加排他锁

 

select * from XXX for update;

 
 
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值