Oracle事务与死锁Content•事务•死锁©2008iSoftStoneHoldingsLtd.AllRightsReserved.事务©2008iSoftStoneHoldingsLtd.AllRightsReserved.事务的简介•Insert•update•delete•select…forupdate•执行第一条语句的时候,事务开始,执行commit或rollback语句的时候事务结束。©2008iSoftStoneHoldingsLtd.AllRightsReserved.事务的简介•事务用来确保数据库数据的一致性,它由一组相关的DML语句组成,这组DML语句要么全成功要么全取消。例如:转账操作,有两步,1.减少帐户的cash2.增加另一个帐户的cash;为了确保数据库的一致性,这两个操作必须全部成功,或者全部都取消。•事务控制有三种:commit,rollback,savepoint.©2008iSoftStoneHoldingsLtd.AllRightsReserved.事务和锁•当执行DML语句的时候,Oracle会在被作用表上加锁,以防止其他用户改变表结构;同时会在被作用行上加锁,以防止其他事务相应行上执行DML操作。updateTc_Testrunsetnstatus=2whereid=1;同时,为了确保数据库数据的读一致性,不允许其他用户读取脏数据(未提交的数据)。©2008iSoftStoneHoldingsLtd.AllRightsReserved.提交事务•使用commit可以提交事务。其他用户可以看到变化后的新数据。•有的情况是自动提交事务。1.当执行DDL语句的时候(create,drop,alert,rename,truncate)。2.当执行DCL语句的时候(grant,revoke)。3.当退出sql*plus的时候©2008iSoftStoneHoldingsLtd.AllRightsReserved.回退事务•Savepoint:保存点是事务中的一点,它用于取消部分事务。当结束事务的时候,会自动删除该事务所定义的所有保存点。在执行rollback的时候,通过指定保存点可以取消部分事务。例如:1.update2.savepointA3.insert,insert4.savepointB5.update•RollbacktoB(取消保存点B后面的操作)•RollbacktoA(取消保存点A后面的操作)•Rollback(取消所有事务操作,并结束事务)©2008iSoftStoneHoldingsLtd.AllRightsReserved.回退事务select*fromTc_Testrun;updateTc_Testrunsetscode='2009001'whereid=1;savepointA;updatetc_testrunsetsCode='2009002'whereid=1;updatetc_testrunsetsschema='Tester'whereid=1;savepointB;updatetc_testrunsetsCode='2009003'whereid=1;select*fromTc_Testrun;rollbacktoB;select*fromTc_Testrun;rollbacktoA;select*fromTc_Testrun;rollback;select*fromTc_Testrun;©2008iSoftStoneHoldingsLtd.AllRightsReserved.回退事务•设置保存点:1.savepointa;2.execdbms_transaction.savepoint(‘a’)•取消部分事务:1.rollbacktoa;2.execdbms_transaction.rollback_savepoint(‘a’)•取消全部事务:1.rollback;2.execdbms_transaction.rollback;©2008iSoftStoneHoldingsLtd.AllRightsReserved.事•事务结束的地方有:1.执行Commit,Rollback,没有使用savepoint.2.执行DDL操作如:create,drop,rename,alter3.断开与Oracle的连接,事务将自动提交。4.用户进程异常终止,当前事务回滚。死锁©2008iSoftStoneHoldingsLtd.AllRightsReserved.数据库死锁的现象•程序在执行的过程中,点击确定或保存按钮,程序没有响应,也没有出现报错。©2008iSoftStoneHoldingsLtd.AllRightsReserved.死锁的原理•当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提交,另一条对于这一列数据做更新操作的语句在执行的时候就会处于等待状态,•此时的现象是这条语句一直在执行,但一直没有执行成功,也没有报错。©2008iSoftStoneHoldingsLtd.AllRightsReserved.死锁的定位方法•通过检查数据库表,能够检查出是哪一条语句被死锁,产生死锁的机器是哪一台1.用dba用户执行以下语句•selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession_idfromv$locked_object)•如果有输出的结果,则说明有死锁,且能看到死锁的机器是哪一台。字段说明:•Username:死锁语句所用的数据库用户;•Lockwait:死锁的状态,如果有内容表示被死锁。•Status:状态,active表示被死锁•Machine:死锁语句所在的机器。•Program:产生死锁的语句主要来自哪个应用程序。©2008iSoftStoneHoldingsLtd.AllRightsReserved.死锁的定位方法2.用dba用户执行以下语句,可以查看到被死锁的语句:selectsql_textfromv$sqlwherehash_valuein(selectsql_hash_valuefromv$sessionwheresidin(selectsession_idfromv$locked_object))©2008iSoftStoneHoldingsLtd.AllRightsReserved.死锁的解决方法•一般情况下,只要将产生死锁的语句提交就可以了,但是在实际的执行过程中。用户可能不知道产生死锁的语句是哪一句。可以将程序关闭并重新启动就可以了。©2008iSoftStoneHoldingsLtd.AllRightsReserved.死锁的解决方法1.查找死锁的进程SELECTs.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#,l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESSFROMV$LOCKED_OBJECTl,V$SESSIONSWHEREl.SESSION_ID=S.SID;2.kill掉这个死锁的进程altersystemkillsession‘sid,serial#’;(其中sid=l.session_id)©2008iSoftStoneHoldingsLtd.AllRightsReserved.死锁的解决方法3.如果还不能解决selectpro.spidfromv$sessionses,v$processprowhereses.sid=XXandses.paddr=pro.addr;•其中sid用死锁的sid替换:exitps-ef|grepspid•其中spid是这个进程的进程号,kill掉这个Oracle进程。©2008iSoftStoneHoldingsLtd.AllRightsReserved.v$lock视图•v$lock视图列出当前系统持有的或正在申请的所有锁的情况,其主要字段说明如下:v$lock视图主要字段说明IDX字段名称类型说明1sidnumber会话(session)标识2typevarchar(2)区分该锁保护对象的类型3id1number锁标识14id2number锁标识25lmodenumber锁模式:0none,1null,2rowshare,3rowexclusive,4share,5sharerowexclusive,6exclusive6requestnumber申请的锁模式:具体值同上面的lmode7ctimenumber已持有或等待锁的时间;8blocknumber是否阻塞其它锁申请©2008iSoftStoneHoldingsLtd.AllRightsReserved.v$lock视图•type字段的取值中,本文只关心tm、tx两种dml锁类型v$lock视图中id1与id2字段取值说明IDXtypeid1id21tm被修改表的标识(object_id)02tx以十进制数值表示该事务所占用的回滚段号与该事务在该回滚段的事务表(transactiontable)中所占用的槽号(slotnumber,可理解为记录号)。其组成形式为:0xrrrrssss(rrrr=rbsnumber,ssss=slot)。以十进制数值表示环绕(wrap)次数,即该槽(slot)被重用的次数©2008iSoftStoneHoldingsLtd.AllRightsReserved.v$locked_object视图•v$locked_object视图列出当前系统中哪些对象正被锁定,其主要字段说明如下:v$locked_object视图字段说明IDX字段名称类型说明1xidusnnumber回滚段号2xidslotnumber槽号3xidsqnnumber序列号4object_idnumber被锁对象标识5session_idnumber持有锁的会话(session)标识6oracle_usernamevarchar2(30)持有该锁的用户的oracle用户名7os_user_namevarchar2(15)持有该锁的用户的操作系统用户名8processvarchar2(9)操作系统的进程号9locked_modenumber同v$lock表的lmode字段