事务(sql事务的管理)

事务:   

  事务是指逻辑上的一组操作,组成这组操作的各个逻辑单元要么一起成功, 要么一起失败。
  mysql的事务管理有两种:(在mysql数据库中直接操作[黑窗口])
    1.手动开启事务:
      a: start transaction;--开启事务
      b: 执行多条sql语句
      c: commit/rollback;--提交事务或者回滚事务
    2.设置一个自动提交参数:
      查看与commmit相关参数:show variables like "%commit%"
      可以查看到一个名为autocommit的属性
      设置autocommit属性值
      set autocommit = 0;--将autocommit的值设置为off,默认是on开启状态。(0代表off,1代表on)
    注意:mysql数据库事务默认是自动提交的; oralce数据库事务默认是不自动提交的。
  jdbc的事务管理
    java.sql.Connection API:
    void setAutoCommit(boolean flag):设置此连接的自动提交状态
    void commit() :提交此连接的事务
    void rollback() :回滚此连接的事务

事务特性:

  原子性:强调事务的不可分割性。
  一致性:强调的是事务的执行前后,数据的完整性要保持一致。
  隔离性:一个事务的执行不应该受到其他事务的干扰。
  持久性:事务一旦结束(commit/rollback)数据就持久到了数据库中。
  注意:如果不考虑事务的隔离性,引发一些安全性问题:
    一类读问题:
      脏读:一个事务读到另一个事务还没有提交的数据。
      不可重复度:;一个事务读到了另一个事务已经提交的update的数据,导致在当前的事务中多次查询结果不一致。  
      虚度/欢度:一个事务读到了另一个事务已经提交的insert数据,导致在当前的事务中多次查询结果不一致。
    一类写问题:
      引发两类丢失更新。
  解决引发的读问题:
    设置事务的隔离级别:
      read uncommitted: 未提交读(脏读,不可重复读,虚度都可能发生)
      read committed: 已提交读(避免脏读,但是不可重复读和虚读有可能发生)
      repeatable read: 可重复度(避免脏读和不可重读读,但是虚读有可能发生)
      serializable: 串行化(避免脏读,不可重复读,虚读的发生)

mysql设置事务的隔离级别:

  查看连接的隔离级别:select @@tx_isolation;

  设置连接(黑窗口)的隔离级别为:read uncommitted:

    set session transaction isolation level read uncommitted;

  设置连接(黑窗口)的隔离级别为:read committed:

    set session transaction isolation level read committed;

  设置连接(黑窗口)的隔离级别为:repeatable read:

    set session transaction isolation level repeatable read;

  设置连接(黑窗口)的隔离级别为:serializable:

    set session transaction isolation level serializable;

jdbc设置事务的隔离级别:

  Connection API:

    void setTransactionIsoLation(int level):设置事务的隔离级别。

注意:不论是通过黑窗口或者jdbc连接数据库都是仅仅建立了一条Connection连接,设置事务隔离级别也是仅仅针对该Connection进行设置。

事务管理两种实现方法:
  一: 将Connection一层层向下传递,DBUtils 进行事务管理使用的就是这种方法。
  二: 在业务层获得connection将这个连接绑定到当前线程中,从当前线程中获取。hibernate底层事务管理使用的是这种方法。

ThreadLocal 本地线程类
  它里面维护的是map,map的key是当前线程,map的value是要绑定的东西,绑定的时候set(value),获取的时候get()获得value。

  示例代码:

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

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JdbcUtils {
    private static final ComboPooledDataSource DATASOURCE = new ComboPooledDataSource();
    private static final ThreadLocal<Connection> TL = new ThreadLocal<Connection>();
    
    public static DataSource getDataSource() {
        return DATASOURCE;
    }
    
    public static Connection getConn() throws SQLException {
        if (TL.get() == null) {
            TL.set(DATASOURCE.getConnection());
        }
        return TL.get();
    }
    
    public static void beginTranscation() throws SQLException {
        if (TL.get() == null) {
            TL.set(DATASOURCE.getConnection());
        }
        TL.get().setAutoCommit(false);
    }
    
    public static void  committranscation() throws SQLException {
        if (TL.get() == null) {
            TL.set(DATASOURCE.getConnection());
        }
        TL.get().commit();
    }
    
    public static void roolbackTranscation() throws SQLException {
        if (TL.get() == null) {
            TL.set(DATASOURCE.getConnection());
        }
        TL.get().rollback();
    }
}
View Code

 

原文地址:https://www.cnblogs.com/laodang/p/9464445.html