数据库事物操作

事务

什么是事务?
转账:
1. 给wc账户减1000元
2. 给wcxf账户加1000元

当给wc账户减1000元后,抛出了异常!这会怎么样呢?我相信从此之后,wc再也不敢转账了。

使用事务就可以处理这一问题:把多个对数据库的操作绑定成一个事务,要么都成功,要么都失败!

---------------------------------------------------------------------------------------------------------------------------------------------

事物的特性:ACID

* 原子性事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
* 一致性事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
* 隔离性隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
* 持久性一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

---------------------------------------------------------------------------------------------------------------------------------------------

MySQL操作事务

1. 开始事务:start transaction
2. 结束事务:commit//提交事物rollback//事物回滚

(1)事物回滚

(2)事物提交

 

 

---------------------------------------------------------------------------------------------------------------------------------------------

JDBC事务

1. 开始事务con.setAutoCommit(false);
2. 结束事务con.commit()con.rollback();

 

public class Jdbc2 {
    public static void main(String[] args) {
        Connection con=null;
        PreparedStatement pst=null;
        try {
            con = JDBCUtils.getConnection();
             //开启事物
            con.setAutoCommit(false);//开启手动事物
            pst=con.prepareStatement("UPDATE  acction SET mun=mun-100 WHERE username=? ");
            pst.setString(1, "zhangsan");
            pst.executeUpdate();
            //人为创建异常
            int index=1/0;
            pst=con.prepareStatement("UPDATE  acction SET mun=mun+100 WHERE username=? ");
            pst.setString(1, "wangwu");
            pst.executeUpdate();
            con.commit();//提交事物
            
        } catch (Exception e) {
            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally{
            //关闭
            JDBCUtils.createClose(null, pst, con);
        }
    }
}

 

 

 

---------------------------------------------------------------------------------------------------------------------------------------------

保存点

保存点的是可以回滚到事务中的某个位置,而不是回滚整个事务。
回滚到保存点不会结束事务。
设置保存点:Savepoint sp = con.setSavepoint();
回滚到保存点:con.rollback(sp);

public class Jdbc1 {
      public static void main(String[] args) {
          Connection con=null;
          PreparedStatement pst=null;
          Savepoint sp=null;
          try{
             con = JDBCUtils.getConnection();
             con.setAutoCommit(false);//手动开启事物
             sp=con.setSavepoint();
             pst=con.prepareStatement("INSERT INTO acction(username,mun) VALUES(?,?)");
             for(int i=1;i<=2000;i++){
                 if(i==1002){
                     int index=i/0;
                 }
                 pst.setString(1, "lxp");
                 pst.setInt(2, i);
                 pst.executeUpdate();
                 if(i%1000==0){
                    sp=con.setSavepoint();
                 } 
             }
             con.commit();//事物提交
          }catch(Exception e){
              try {
                con.rollback(sp);
                con.commit();
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }//回滚事物
              e.printStackTrace();
          }finally{
              JDBCUtils.createClose(null, pst, con) ;
          }
    }

---------------------------------------------------------------------------------------------------------------------------------------------

事务隔离级别

* 脏读:读到未提交


* 不可重复读:两次读取不一致,读取到另一事务修改的记录


* 幻读:两次读取不一致,读取到另一事务插入的记录

---------------------------------------------------------------------------------------------------------------------------------------------

四大隔离级别
* SERIALIZABLE(串行化):对同一数据的访问是串行的,即非并发的,所以不会出现任何并发问题。易出现死锁,效率太低!不可用!
* REPEATABLE READ(可重复读):防止了脏读、不可重复读,但没有防止幻读
* READ COMMITTED(读已提交):防止了脏读,但没有防止不可重复读,以及幻读
* READ UNCOMMITTED(读未提交):可能出现所有并发问题,效率最高,但不可用!

MySQL默认事务隔离级别为:REPEATABLE READ
Oracle默认事务隔离级别为:READ COMMITTED

-------------------------------------------------------------------------------------------------------------------------------------------------

MySQL设置事务隔离级别

/* 查看:*/select @@tx_isolation
/* 设置:*/set transaction isolation level 四选一

JDBC设置事务隔离级别

con.setTransactionIsolation(四选一)

------------------------------------------------------------------------------------------------------------------------------------------------------

代码JDBCUtils代码:

需要配置dbconfig.properties文件

 

public class JDBCUtils {
    static Properties props = null;
    //绑定线程
    static private ThreadLocal<Connection> t1=new ThreadLocal<Connection>();
    static {
        // 加载本地配置文件
        try {
            InputStream in = JDBCUtils.class
                    .getResourceAsStream("dbconfig.properties");
            props = new Properties();
            props.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 加载驱动
        try {
            Class.forName(props.getProperty("driverClassName"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    /**
     * 获得Connection连接
     * @return
     * @throws Exception
     */
    public static Connection getConnection() throws Exception {
        Connection conn = t1.get();
        if(conn==null){
        // 加载配合
         conn= DriverManager.getConnection(props.getProperty("url"),
                props.getProperty("username"), props.getProperty("password"));
        t1.set(conn);
        }
        return conn;
    }
   /**
    * 关闭所有连接
    * @param rs
    * @param statement
    * @param conn
    */
    public static void createClose(ResultSet rs, PreparedStatement statement,
            Connection conn) {
        try {
            if (rs != null)
                rs.close();
            if (rs != null)
                statement.close();
            if (rs != null)   
                conn.close();
    if(t1!=null){
                t1.remove();
            } }
catch (Exception e) { e.printStackTrace(); } } }

 

posted @ 2017-03-29 14:50  晓梦蝶  阅读(1439)  评论(0编辑  收藏  举报