javaJDBC(4)-事务、隔离级别



说明:这里列出了数据库操作的重要内容---事务,假设银行为了转账而对数据库操作,执行减钱成功了,但是加钱的时候出问题了,这就坏了。事务就是可以让多个动作都成功之后再生效,否则都不生效。

package cn.itcast.jdbc;

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

import org.junit.Test;

import cn.itcast.util.JdbcUtil;

/*
create table account(
 id int primary key auto_increment,
 name varchar(40),
 money float
);
insert into account(name,money) values(‘aaa‘,1000);
insert into account(name,money) values(‘bbb‘,1000);
insert into account(name,money) values(‘ccc‘,1000);
 */
public class TransactionDemo1 {
 @Test
 public void test(){
  Connection conn = null;
  PreparedStatement stmt = null;
  try{//事务本来是默认开启的,执行依据关闭
   conn = JdbcUtil.getConnection();
   //手工开启事务
   conn.setAutoCommit(false);//相当于start transaction;
   stmt = conn.prepareStatement("update account set money=money-100 where name=‘bbb‘");
   stmt.executeUpdate();
   //int i = 1/0;//这里是异常,用于测试
   stmt = conn.prepareStatement("update account set money=money+100 where name=‘aaa‘");
   stmt.executeUpdate();
   conn.commit();//事务提交
  }catch(Exception e){
   e.printStackTrace();//如果中间出现
   try {
    conn.rollback();
   } catch (SQLException e1) {
    e1.printStackTrace();
   }
  }finally{
   JdbcUtil.release(null, stmt, conn);
  }
 }

}


下面是事务的隔离级别:


事务的特性(隔离级别)
A:原子性。说明事务是一个不可分割的单位。
C:一致性.事务必须使数据库从一个一致性状态变换到另外一个一致性状态.(比如转账)
*I:隔离性。一个事务不能被其他事务打扰。
D:持久性。事务一旦提交,就应该被永久保存起来。

如果不考虑事务的隔离级别,会出现以下“不正确”的情况:
脏读:指一个事务读到了另一个事务中未提交的数据。
不可重复读:针对一条记录的,同一条记录前后不一样
虚读(幻读):针对一张表,前后读到的记录条数不一样。

MySQL中控制事务隔离级别的语句:
select @@tx_isolation;     //查看当前的事务隔离级别
set transaction isolation level 你的级别(四种之一);//设置隔离级别



隔离级别的分类:
READ UNCOMMITTED:脏读、不可重复读、虚读都有可能发生。
READ COMMITTED:能避免脏读,不可重复读、虚读都有可能发生。
REPEATABLE READ:能避免脏读、不可重复度,虚读都有可能发生。
SERIALIZABLE:能避免脏读、不可重复度、虚读。

package cn.itcast.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;

import cn.itcast.util.JdbcUtil;
//演示控制事务的隔离级别
//隔离级别必须用在事务之中
public class TransactionIsolationDemo {
 @Test
 public void test(){
  Connection conn = null;
  PreparedStatement stmt = null;
  ResultSet rs = null;
  try{
   conn = JdbcUtil.getConnection();
   conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);//一定要在开启事务前设置隔离级别,否则无效
   conn.setAutoCommit(false);
   //先查询aaa的余额
   stmt = conn.prepareStatement("select * from account where name=‘aaa‘");
   rs = stmt.executeQuery();
   if(rs.next())
    System.out.println("开始时的余额:"+rs.getString("money"));
   
   Thread.sleep(10*1000);
   
   stmt = conn.prepareStatement("select * from account where name=‘aaa‘");
   rs = stmt.executeQuery();
   if(rs.next())
    System.out.println("别人未提交事务时的余额:"+rs.getString("money"));
   
  }catch(Exception e){
   e.printStackTrace();
   try {
    conn.rollback();
   } catch (SQLException e1) {
    e1.printStackTrace();
   }
  }finally{
   try {
    conn.commit();
   } catch (SQLException e) {
    e.printStackTrace();
   }

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。