好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

JDBC事务隔离级别和db2中几个隔离级别行锁等.docx

4页
  • 卖家[上传人]:宝路
  • 文档编号:20926867
  • 上传时间:2017-11-22
  • 文档格式:DOCX
  • 文档大小:27.80KB
  • / 4 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 事务隔离级别和 db2 中几个隔离级别行锁等聊记下对应的事务处理问题 ———工作中头疼的事务拆分,降低事务的–文字简介–JDBC 的数据隔离级别设置:JDBC 数据库隔离级别 数据访问情况TRANSACTION_READ_UNCOMMITTED ur 就是俗称“脏读” (dirty read) ,在没有提交数据时能够读到已经更新的数据TRANSACTION_READ_COMMITTED cs 在一个事务中进行查询时,允许读取提交前的数据,数据提交后,当前查询就可以读取到数据update 数据时候并不锁住表TRANSACTION_REPEATABLE_READ rs 在一个事务中进行查询时,不允许读取其他事务 update 的数据,允许读取到其他事务提交的新增数据TRANSACTION_SERIALIZABLE rr 在一个事务中进行查询时,不允许任何对这个查询表的数据修改JDBC 事务隔离级别为了解决与“多个线程请求相同数据”相关的问题,事务之间用锁相互隔开多数主流的数据库支持不同类型的锁;因此,JDBC API 支持不同类型的事务,它们由 Connection 对象指派或确定在 JDBC API 中可以获得下列事务级别:TRANSACTION_NONE 说明不支持事务。

      TRANSACTION_READ_UNCOMMITTED 说明在提交前一个事务可以看到另一个事务的变化这样脏读、不可重复的读和虚读都是允许的TRANSACTION_READ_COMMITTED 说明读取未提交的数据是不允许的这个级别仍然允许不可重复的读和虚读产生TRANSACTION_REPEATABLE_READ 说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现TRANSACTION_SERIALIZABLE 是最高的事务级别,它防止脏读、不可重复的读和虚读 为了在性能与一致性之间寻求平衡才出现了上面的几种级别事务保护的级别越高,性能损失就越大假定您的数据库和 JDBC 驱动程序支持这个特性,则给定一个 Connection 对象,您可以明确地设置想要的事务级别:1 conn.setTransactionLevel(TRANSACTION_SERIALIZABLE) ;可以通过下面的方法确定当前事务的级别:123456int level = conn.getTransactionIsolation();if(level == Connection.TRANSACTION_NONE)System.out.println("TRANSACTION_NONE");else if(level == Connection.TRANSACTION_READ_UNCOMMITTED)System.out.println("TRANSACTION_READ_UNCOMMITTED");7891011else if(level == Connection.TRANSACTION_READ_COMMITTED)System.out.println("TRANSACTION_READ_COMMITTED");else if(level == Connection.TRANSACTION_REPEATABLE_READ)System.out.println("TRANSACTION_REPEATABLE_READ");else if(level == Connection.TRANSACTION_SERIALIZABLE)System.out.println("TRANSACTION_SERIALIZABLE");DB2 中隔离级别和锁的各种用法和机制基于 db2 9 中做了以下的试验12345678910111213141516171819202122232425262728293031323334CREATE TABLE RRTest (pkID VARCHAR(20) NOT NULL ,unID1 VARCHAR(20) NOT NULL,UnID2 VARCHAR(20) ,"CUSTOMER_ID" VARCHAR(6) ,"ORDER_TYPE" DECIMAL(2,0) , "EXECUTION_TYPE" DECIMAL(2,0) , "ORDER_DATE" VARCHAR(8) , "ORDER_TIME" VARCHAR(6) , "ORDER_DATETIME" TIMESTAMP , "SIDE" DECIMAL(1,0) , "TRADE_TYPE" DECIMAL(1,0) , "ORDER_AMOUNT" DECIMAL(15,2) , "ORDER_PRICE" DECIMAL(8,4),TSID VARCHAR(20) ) INSERT INTO RRTest SELECT Order_ID, Order_ID, Order_ID, CUSTOMER_ID, ORDER_TYPE, EXECUTION_TYPE, ORDER_DATE, ORDER_TIME, ORDER_DATETIME, SIDE, TRADE_TYPE, ORDER_AMOUNT, ORDER_PRICE ,ORDER_IDFROM DB2INST1.Fx_Order WHERE ORDER_DATE >'20070401'GOSELECT COUNT(*) FROM RRTEST72239ALTER TABLE "DB2INST1".RRTestADD PRIMARY KEY(pkID);CREATE UNIQUE INDEX UNIQINDX ON RRTest(unID1)CREATE INDEX INDX002 ON RRTest(unID2)db2 "RUNSTATS ON TABLE DB2INST1.RRTest ON ALL COLUMNS AND INDEXES ALL ALLOW WRITE ACCESS"3536373839404142434445464748495051db2 CONNECT TO db2TTdb2 +cSELECT * FROM RRTEST WHERE TSID='20070223ORD01267732' FOR UPDATE WITH RRSELECT * FROM RRTEST WHERE TSID='20070222ORD01266302' FOR UPDATE WITH RRSELECT * FROM RRTEST WHERE TSID='20070223ORD01267732' FOR UPDATE WITH RSSELECT * FROM RRTEST WHERE TSID='20070222ORD01266302' FOR UPDATE WITH RSSELECT * FROM RRTEST WHERE unID1='20070223ORD01267732' FOR UPDATE WITH RRSELECT * FROM RRTEST WHERE unID1='20070222ORD01266302' FOR UPDATE WITH RRSELECT * FROM RRTEST WHERE unID1='20070223ORD01267732' FOR UPDATE WITH RSSELECT * FROM RRTEST WHERE unID1='20070222ORD01266302' FOR UPDATE WITH RSSELECT * FROM RRTEST WHERE unID2='20070223ORD01267732' FOR UPDATE WITH RRSELECT * FROM RRTEST WHERE unID2='20070222ORD01266302' FOR UPDATE WITH RRSELECT * FROM RRTEST WHERE unID2='20070223ORD01267732' FOR UPDATE WITH RSSELECT * FROM RRTEST WHERE unID2='20070222ORD01266302' FOR UPDATE WITH RSSELECT * FROM RRTEST WHERE pkID='20070223ORD01267732' FOR UPDATE WITH RRSELECT * FROM RRTEST WHERE pkID='20070222ORD01266302' FOR UPDATE WITH RRSELECT * FROM RRTEST WHERE pkID='20070223ORD01267732' FOR UPDATE WITH RSSELECT * FROM RRTEST WHERE pkID='20070222ORD01266302' FOR UPDATE WITH RS按照以上字段 pkID 是主键,unID1 是唯一健索引,unID2 是普通健索引,TSID 是普通字段,没有在上建立索引。

      试验结论:PK_INDEX UNIQ_INDEX NormalINDEX NO_INDEXWITH RR 锁行,不锁表 锁行,不锁表 不锁行,不锁表(1) 锁行,锁表WITH RS 锁行,不锁表 锁行,不锁表 锁行,不锁表 锁行,锁表(2)锁行是指在一个事务中用某种方式读取并更改了改行数据并显示得指明要修改后,这个事务将锁住改行,直到它提交或者回滚了事务后,才释放该锁锁表是指在用以上各种 SQL 在读取并更改一行的同时锁住了整个表对以上红字部分(1)可能有不能理解的是:为什么对普通索引和主键或者唯一健索引的不同结论? 对 PK 和 UNIQ 的解释是因为 RR 是可重复的读的级别,对这次检索扫描到的有可能成为自己的潜在检索对象的内容都会锁住,而因为是主键或者唯一健,别的行不可能成为这次这个检索的潜在读的范围,就是对别的数据此事务根本就没有必要锁,任何情况的更改都不可能出现幻读的情况(此表上的约束限制),所以只锁这一行这么理解对 PK,UNIQ 没有问题但是 NormalINDEX 我认为应该是锁住这个表而不是不锁这点一直没想明白留待以后再加强理解对 RS隔离级别是“锁定检索到的数据行”,是通过 SQL 检索到的结果进行锁定, PK,UNIQ,INDEX 的结论完全都可以理解。

       对 tableScan 的检索而出现的锁表有些象 RR 隔离级别的所为遇到此类并发控制程序中注意一下,select * From TTT where ****= ? for update with RR(RS),这里的 *** 可不是随便定义的隔离级别分为 RR/RS/CS/UR 这四个级别 下面让我们来逐一论述:1. RR 隔离级别: 在此隔离级别下, DB2 会锁住所有相关的纪录 在一个SQL 语句执行期间, 所有执行此语句扫描过的纪录都会被加上相应的锁 具体的锁的类型还是由操作的类型来决定, 如果是读取,则加共享锁; 如果是更新, 则加独占锁 由于会锁定所有为获得 SQL 语句的结果而扫描的纪录, 所以锁的数量可能会很庞大, 这个时候, 索引的增加可能会对 SQL 语句的执行有很大的影响,因为索引会影响 SQL 语句扫描的纪录数量2. RS 隔离级别: 此隔离级别的要求比 RR 隔离级别稍弱,此隔离级别下会锁定所有符合条件的纪录 不论是读取, 还是更新, 如果 SQL 语句中包含查询条件, 则会对所有符合条件的纪录加相应的锁 如果没有条件语句, 也就是对表中的所有记录进行处理,则会对所有的纪录加锁。

      3. CS 隔离级别: 此隔离级别仅锁住当前处。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.