• 事务和锁


    昨天已经写了一次,从图书馆走的时候忘了保存直接关了窗口,心痛。。。

    事务是面试时候几乎必问的。虽然心里明白但是无法给出准确回答,再来温习一下。

    一。什么是事务

    书中的定义是这样的:

       事务就是一组包含一条或多条语句的逻辑单元,每个事务都是一个原子单位,在事务中的语句被作为一个整体, 
    要么一起被提交,作用在数据库上,使数据库中数据永久的修改;要么一起被撤销,对数据库不做任何的改变

    我理解的是事务是维持数据库中数据的完整性和一致性的必要条件。

    每当谈起事务最经典的例子就是银行账户之间的汇款转账操作。这必须是一个原子性的操作。

    整个操作在数据库中分为三个过程:

    银行从甲方取出钱;

    银行把钱存入乙方;

    在事务日志中记录该事务

    这个交易过程,看做一个事务,如果操作失败,事务就会回滚,所有操作都会撤销,目标账户和源账户上的钱都不会改变;操作成功那么就会被永久提交,目标账户和源账户上的金额都改变了。所以说根据这个例子好好理解一下事务,就是一组操作看做一个整体,要是有一个操作失败了,那就从头来过,不可能说从甲方弄出钱去,还没到乙那失败了,甲方这钱也回不来了,这是不存在的,要是这个整体都成功了,那就成既定事实了,甲方的余额就会减少,乙方的余额就会增多。

    事务大概理解了,那到底什么情况才是事务呢?这时候就要看看事务的特性:

    1.原子性:原子意味着不可分割,也就是说事务是一个整体,要么全部执行,要么全部不执行,如果都执行成功才可以,即使事务里面一个操作错了,其余的全部成功了,那也不行。操作会被事务撤销。

    2.一致性:一致性就是事务执行前后数据库都必须处于一致性状态,只有事务完成后才能被所有使用者看见。例如从甲方取款但是还没有放到乙账户时数据库是不一致的,也是不完整的,其他使用者例如丙并不知道A中修改后的数据,只有存到乙方账户中,交易完成并提交事务,这时才算事务一致,其他用户才能看到修改后的数据。

    3.分离性:并发事务之间不能相互的干扰,也就是说,一个事务操作的数据不会被其他事务看到和操作。想一下,甲给乙转钱的同时乙也给甲转,如果事务不分离那不乱套了,想想都乱

    4.持久性:一旦成功,数据库中的数据会永久改变。

    事务怎么控制呢?

    set  transaction:设置事务的属性

    commit 提交事务

    savepoint:设置保存点

    rollback:回滚事务

    rollback to savepoint :回滚至保存点

    二。事务的类型

    事务分为两种类型

    1.显示方式

    新事务开始
    sql statement
    ...
    commit|rollback;

    oracle中的事务不需要设置开始标志,通常遇到  1.登录数据库后,第一次执行DML语句;当事务结束后,第一次执行DML语句。 事务会开启

    2.隐式方式

    没有明确的开始和结束标志,由数据库自动开启,当一个程序正常结束或使用DDL语言时会自动提交,而操作失败时也会自动回滚。如果autocommit 为打开 状态,则每一次执行DML语句都会自动提交。

    事务在 1.使用commit提交,使用rollback回滚 2.执行DDL语句,是误会自动提交 3.正常退出SQL*PLUS 时自动提交事务,非正常退出会rollback回滚事务 。 时会结束。

    三。事务的保存点

    保存点可以根据自己的需要去设置,比如一个事务前十条语句确定没错,就可以在第十条操作结束后设置保存点,这样即使后面的语句错了,回滚到这个保存点就可以。

    需要注意的几点是:1.事务只回滚保存点之后的操作 2.回滚到保存点时,它以后的保存点将被删除,但保存点会被保留 3.保存点之后的锁将被释放,但之前的会被保留

    如果在事务中使用保存点呢?

    四。 锁

    锁学过java并不陌生,数据库中锁和java中是不是一样呢?来看看锁在数据库中的作用

    锁出现在数据共享的的环境中,它是一种机制,在访问相同资源时,可以防止事务之间的破坏性交互。来考虑一下事务的特性,事物的分离性要求当前事务不能影响其他的事务,所以当多个会话访问相同的资源时,数据库系统会利用锁确保它们像队列一样一次进行

    来看看锁的分类

    1.排他锁(X锁) 也可以叫做写锁,这种模式的锁防止资源的共享,用作数据的修改,假如有事务T给数据A加上该锁,那么其他的事务将不能对A加任何的锁,所以此时只允许T对改数据进行读取和修改,知道事务完成将该类型的锁释放

    2.共享锁(S锁)也可以叫读锁,该模式锁下的数据只能被读取,不能被修改,如果有事务T给数据A加上共享锁之后,那么其他事物不能对其加排他锁,只能加共享锁,加了该所得数据可以被并发的读取。

    再来看看锁的类型

    oracle为了使数据库实现高度的并发访问,它使用了不同类型的锁来管理并发会发对数据对象的操作。

    按作用对象不同分为

     1.DML锁:数据锁,用于保护数据

    2.DDL锁:可以保护模式中对象的结构

    3.内部闩锁:保护数据库的内部结构,完全自动调用。

    其中DML锁主要保证了并发访问时数据的完整性,如果再细分,它又可以分为

    1)行级锁(TX)也可以称为事务锁。当修改表中某行数据时,需要对将要修改的记录加行级锁,防止两个事务同时修改相同记录,事务结束,该锁也会释放,是粒度最小的锁。属于排他锁(X锁)

    2)表级锁(TM)主要作用是防止在修改表的数据时,表的结构发生变化。例如,会话S在修改表A的数据时它会得到表A的TM锁,而此时将不允许其他会话对该表进行变更或删除操作。

    来验证一下

    首先第一个会话对pro进行修改,获取TM锁,这时候另一个会话想删除pro就会报错

    表级锁包含如下几种模式

    oracle中除了执行DML时自动加锁以外,还可以自己添加,语法是

    lock table table in
       [row share]
       [row exclusive]
       [share]
       [share row exclusive]
       [exclusive]
     mode [nowalt]

    如果要释放,则需要rollback命令

    DDL锁又叫做数据字典锁,主要作用是保护模式中对象的结构。当执行DDL操作时,首先oracle会自动隐式提交一次事务,然后自动给处理对象加上所,当DDL结束时,oracle会隐式地提交书屋并释放DDL锁。与DML不同的是,用户不能显式地要求使用DDL锁。

    分为三种

    1。exclusive ddl lock  排他DDL锁定

    2. shared ddl lock 共享DDL锁定

    3.breakable parsed lock   

    锁等待与死锁

    锁等待是因为占用的资源不能及时释放,而造成的,上面的例子中,一个花花修改表pro的记录,如果不提交,那么另一个会话就一直没法对pro进行操作

    死锁与锁等待不同,它是锁等待的一个特例,通常发生在两个或多个会话之间。假如一个会话想要修改两个资源对象,可以是表也可以是字段,修改这两个资源的操作在一个事务当中。当它修改第一个对象时需要对其锁定,然后等待第二个对象,这时如果另外一个会话也需要修改这两个资源对象,并且易筋经获得并锁定了第二个对象,那么就会出现思索,因为当前会话锁定了第一个对象等待第二个对象,而另一个会话锁定了第二个对象等待第一个对象

  • 相关阅读:
    Struts2中ModelDriven的使用
    Android 如何让 app 自行处理 power key M
    url后面带斜杠与不带斜杠的区别
    Http Request Method:options
    org.springframework.boot.builder.SpringApplicationBuilder.<init>
    Uncaught (in promise) DOMException: Failed to execute 'open' on 'XMLHttpRequest': Invalid URL
    git将多个commit合并成一个
    idea error:Command line is too long
    java使用zxing插件绘制二维码
    git解决冲突插件之Beyond Compare
  • 原文地址:https://www.cnblogs.com/wxw7blog/p/7792884.html
Copyright © 2020-2023  润新知