Java

事务

2018-12-25  本文已影响3人  强某某

事务

Transaction 一组操作包含多个单一操作,一组操作必须同事成功或者失败(回滚)

-- 显示是否自动提交(事务)
SHOW VARIABLES LIKE '%commit%'
-- 关闭自动提交
SET autocommit  =off

-- 开启事务
START transaction
-- 回滚和提交
rollback   commit

代码实例

代码的事务,主要是针对连接来的

1. 关闭自动提交
2. 开启事务
3. 提交
4. 异常回滚事务
@Test
    public void testQuery() throws SQLException {
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            //jdbc默认事务是自动提交的
             conn = JDBCUtil.getConn();
             //关闭自动提交
             conn.setAutoCommit(false);
             String sql="update student set age=age-? where sex=?";
              ps = conn.prepareStatement(sql);
              ps.setInt(1, 1);
              ps.setInt(2, 31);
              ps.executeUpdate();
              ps.setInt(1, -1);
              ps.setInt(2, 2);
              ps.executeUpdate();
            //提交事务
              conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            //回滚事务
            conn.rollback();
        }finally {
            JDBCUtil.release(conn, ps, rs);
        }
    }

ACID


  1. 原子性

    事务中包含的逻辑不可分割

  2. 一致性

    事务执行前后,数据完整性保持一致

  3. 隔离性

    事务在执行期间,不应该受到其他事务的影响

  4. 持久性

    事务执行成功,数据应该持久保存到磁盘上


隔离级别


  1. Read Uncommitted 读未提交
  2. Read Commited 读已提交
  3. Repeatable Read 重复读
  4. Senalizable 可串行化(事务排队,先开启事务的执行完毕,其他事务才能有动作)

set session transaction isolation level read uncommitted;


安全问题


  1. 读问题 :
    • 脏读(读取的是内存中数据,而不是磁盘中数据,可通过读已提交隔离级别解决该问题)
    • 不可重复读(在隔离级别是读已提交情况下,因为读取是已提交的,所以可能出现前后读取数据不一致,可能上一次读时候还没提交,
      前端两次读取结果不同,这就是不可重复读,可以利用重复度隔离级别避免该问题)
    • 幻读(一个事务读到另一个事务已提交的插入的数据,导致查询结果不一致,通过可串行化解决,但是性能低)
  2. 写问题 : 丢失更新

    解决方案
    * 2.1 悲观锁(一定会丢失更新)
    > 查询时候加上for update


    悲观锁.png

    * 2.2 乐观锁(一定不会丢失更新)
    > 要求程序员自己控制,比如此时手动比较version,如果不符合version,则重新查询


    乐观锁.png

-- 查询隔离级别(mysql默认是重复读)
SELECT @@tx_isolation;
上一篇 下一篇

猜你喜欢

热点阅读