首页 07_transaction.pdf

07_transaction.pdf

07_transaction.pdf

上传者: 小公子 2011-06-21 评分1 评论0 下载7 收藏0 阅读量776 暂无简介 简介 举报

简介:本文档为《07_transactionpdf》,可适用于软件工程领域,主题内容包含数据库事务与并发n教学内容n数据库事务的概念n声明事务边界n并发问题n设置事务隔离级别n使用悲观锁解决并发问题n使用乐观锁解决并发问题PDF文件使用符等。

数据库事务与并发n教学内容n数据库事务的概念n声明事务边界n并发问题n设置事务隔离级别n使用悲观锁解决并发问题n使用乐观锁解决并发问题PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn数据库事务的概念n事务是指一组相互依赖的操作行为如银行交易、股票交易或网上购物。事务的成功取决于这些相互依赖的操作行为是否都能执行成功只要有一个操作行为失败就意味着整个事务失败。例如Tom到银行办理转账事务把元钱转到Jack的账号上这个事务包含以下操作行为:n()从Tom的账户上减去元。n()往Jack的账户上增加元。n显然以上两个操作必须作为一个不可分割的工作单元。假如仅仅第一步操作执行成功使得Tom的账户上扣除了元但是第二步操作执行失败Jack的账户上没有增加元那么整个事务失败。n数据库事务是对现实生活中事务的模拟它由一组在业务逻辑上相互依赖的SQL语句组成。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn数据库事务的生命周期PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcnMySQL数据库系统的客户程序PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn声明事务的边界n事务的开始边界。n事务的正常结束边界(COMMIT):提交事务永久保存被事务更新后的数据库状态。n事务的异常结束边界(ROLLBACK):撤销事务使数据库退回到执行事务前的初始状态。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn在mysqlexe程序中声明事务n每启动一个mysqlexe程序就会得到一个单独的数据库连接。每个数据库连接都有个全局变量autocommit表示当前的事务模式它有两个可选值:n:表示手工提交模式。n:默认值表示自动提交模式。n如果要察看当前的事务模式可使用如下SQL命令:nmysql>selectautocommitn如果要把当前的事务模式改为手工提交模式可使用如下SQL命令:nmysql>setautocommit=PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn在MySQL中创建支持事务的表n在MySQL中数据库表分为三种类型:INNODB、BDB和MyISAM类型。其中InnoDB和BDB类型的表支持数据库事务而MyISAM类型的表不支持事务。在MySQL中用createtable语句新建的表默认为MyISAM类型。如果希望创建INNODB类型的表可以采用以下形式的DDL语句:createtableACCOUNTS(IDbigintnot,NAMEvarchar(),BALANCEdecimal(,),primarykey(ID))type=INNODBPDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn在自动提交模式下运行事务n在自动提交模式下每个SQL语句都是一个独立的事务。如果在一个mysqlexe程序中执行SQL语句:nmysql>insertintoACCOUNTSvalues(,'Tom',)nMySQL会自动提交这个事务这意味着向ACCOUNTS表中新插入的记录会永久保存在数据库中。此时在另一个mysqlexe程序中执行SQL语句:nmysql>select*fromACCOUNTSn这条select语句会查询到ID为的ACCOUNTS记录。这表明在第一个mysqlexe程序中插入的ACCOUNTS记录被永久保存这体现了事务的ACID特性中的永久性。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn在手工提交模式下运行事务n在手工提交模式下必须显式指定事务开始边界和结束边界:n事务的开始边界:beginn提交事务:commitn撤销事务:rollbackPDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn在手工提交模式下运行事务n()启动两个mysqlexe程序在两个程序中都执行以下命令以便设定手工提交事务模式:nmysql>setautocommit=n()在第一个mysqlexe程序中执行SQL语句:nmysql>beginnmysql>insertintoACCOUNTSvalues(,'Jack',)n()在第二个mysqlexe程序中执行SQL语句:nmysql>beginnmysql>select*fromACCOUNTSnmysql>commitn以上select语句的查询结果中并不包含ID为的ACCOUNTS记录这是因为第一个mysqlexe程序还没有提交事务。n()在第一个mysqlexe程序中执行以下SQL语句以便提交事务:nmysql>commitn()在第二个mysqlexe程序中执行SQL语句:nmysql>beginnmysql>select*fromACCOUNTSnmysql>commitn此时select语句的查询结果中会包含ID为的ACCOUNTS记录这是因为第一个mysqlexe程序已经提交事务。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn通过JDBCAPI声明事务边界nConnection类提供了以下用于控制事务的方法:nsetAutoCommit(booleanautoCommit):设置是否自动提交事务ncommit():提交事务nrollback():撤销事务PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn通过JDBCAPI声明事务边界try{con=javasqlDriverManagergetConnection(dbUrl,dbUser,dbPwd)设置手工提交事务模式consetAutoCommit(false)stmt=concreateStatement()数据库更新操作stmtexecuteUpdate("updateACCOUNTSsetBALANCE=whereID=")数据库更新操作stmtexecuteUpdate("updateACCOUNTSsetBALANCE=whereID=")concommit()提交事务}catch(Exceptione){try{conrollback()操作不成功则撤销事务}catch(Exceptionex){处理异常……}处理异常……}finally{…}PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn通过HibernateAPI声明事务边界n声明事务的开始边界:Transactiontx=sessionbeginTransaction()n提交事务:txcommit()n撤销事务:txrollback()PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn多个事务并发运行时的并发问题n第一类丢失更新:撤销一个事务时把其他事务已提交的更新数据覆盖。n脏读:一个事务读到另一事务未提交的更新数据。n虚读:一个事务读到另一事务已提交的新插入的数据。n不可重复读:一个事务读到另一事务已提交的更新数据。n第二类丢失更新:这是不可重复读中的特例一个事务覆盖另一事务已提交的更新数据。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn取款事务和支票转账事务n取款事务包含以下步骤:n()某银行客户在银行前台请求取款元出纳员先查询账户信息得知存款余额为元。n()出纳员判断出存款额超过了取款额就支付给客户元并将账户上的存款余额改为元。n支票转账事务包含以下步骤:n()某出纳员处理一转帐支票该支票向一帐户汇入元。出纳员先查询账户信息得知存款余额为元。n()出纳员将存款余额改为元。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn并发运行的两个事务导致脏读取款事务在T时刻把存款余额改为元支票转账事务在T时刻查询账户的存款余额为元取款事务在T时刻被撤销支票转账事务在T时刻把存款余额改为元。由于支票转账事务查询到了取款事务未提交的更新数据并且在这个查询结果的基础上进行更新操作如果取款事务最后被撤销会导致银行客户损失元。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn并发运行的两个事务导致第二类丢失更新取款事务在T时刻根据在T时刻的查询结果把存款余额改为元在T时刻提交事务。支票转账事务在T时刻根据在T时刻的查询结果把存款余额改为元。由于支票转账事务覆盖了取款事务对存款余额所做的更新导致银行最后损失元。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn数据库的事务隔离级别PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn隔离级别与并发性能的关系PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn设定隔离级别的原则n隔离级别越高越能保证数据的完整性和一致性但是对并发性能的影响也越大。n对于多数应用程序可以优先考虑把数据库系统的隔离级别设为ReadCommitted它能够避免脏读而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题在可能出现这类问题的个别场合可以由应用程序采用悲观锁或乐观锁来控制。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn在mysqlexe程序中设置隔离级别n每启动一个mysqlexe程序就会获得一个单独的数据库连接。每个数据库连接都有个全局变量txisolation表示当前的事务隔离级别。MySQL默认的隔离级别为RepeatableRead。如果要察看当前的隔离级别可使用如下SQL命令:nmysql>selecttxisolationn如果要把当前mysqlexe程序的隔离级别改为ReadCommitted可使用如下SQL命令:nmysql>settransactionisolationlevelreadcommittedPDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn在Hibernate中设置隔离级别n在Hibernate的配置文件中可以显式的设置隔离级别。每一种隔离级别都对应一个整数:n:ReadUncommittedn:ReadCommittedn:RepeatableReadn:Serializablen例如以下代码把hibernateproperties文件中的隔离级别设为ReadCommitted:hibernateconnectionisolation=对于从数据库连接池中获得的每个连接Hibernate都会把它改为使用ReadCommitted隔离级别。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn使用悲观锁Accountaccount=(Account)sessionget(Accountclass,newLong(),LockModeUPGRADE)accountsetBalance(accountgetBalance())Hibernate执行的select语句为:select*fromACCOUNTSwhereID=forupdateupdateACCOUNTSsetBALANCE=…PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn利用悲观锁协调并发运行的取款事务和支票转账事务PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn使用乐观锁n乐观锁是由应用程序提供的一种机制这种机制既能保证多个事务并发访问数据又能防止第二类丢失更新问题。n在应用程序中可以利用Hibernate提供的版本控制功能来实现乐观锁。对象关系映射文件中的<version>元素和<timestamp>元素都具有版本控制功能:n<version>元素利用一个递增的整数来跟踪数据库表中记录的版本n<timestamp>元素用时间戳来跟踪数据库表中记录的版本。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn利用<version>元素对ACCOUNTS表中记录进行版本控制n()在Account类中定义一个代表版本信息的属性:privateintversionpublicintgetVersion(){returnthisversion}publicvoidsetVersion(intversion){thisversion=version}PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn利用<version>元素对ACCOUNTS表中记录进行版本控制n()在ACCOUNTS表中定义一个代表版本信息的字段:createtableACCOUNTS(IDbigintnot,NAMEvarchar(),BALANCEdecimal(,),VERSIONinteger,primarykey(ID))type=INNODBPDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn利用<version>元素对ACCOUNTS表中记录进行版本控制n()在Accounthbmxml文件中用<version>元素来建立Account类的version属性与ACCOUNTS表中VERSION字段的映射:<idname="id"type="long"column="ID"><generatorclass="increment"><id><versionname="version"column="VERSION">……PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn利用<version>元素对ACCOUNTS表中记录进行版本控制n当Hibernate更新一个Account对象时会根据它的id与version属性到ACCOUNTS表中去定位匹配的记录假定Account对象的version属性为那么在取款事务中Hibernate执行的update语句为:updateACCOUNTSsetNAME=’Tom’,BALANCE=,VERSION=whereID=andVERSION=n如果存在匹配的记录就更新这条记录并且把VERSION字段的值加。当支票转账事务接着执行以下update语句时:updateACCOUNTSsetNAME=’Tom’,BALANCE=,VERSION=whereID=andVERSION=n由于ID为的ACCOUNTS记录的版本已经被取款事务修改因此找不到匹配的记录此时Hibernate会抛出StaleObjectStateException。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn利用<version>元素对ACCOUNTS表中记录进行版本控制n在应用程序中应该捕获该异常这种异常有两种处理方式:n方式一:自动撤销事务通知用户账户信息已被其他事务修改需要重新开始事务。n方式二:通知用户账户信息已被其他事务修改显示最新存款余额信息由用户决定如何继续事务用户也可以决定立刻撤销事务。PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn利用<version>元素对ACCOUNTS表中记录进行版本控制try{tx=sessionbeginTransaction()logwrite("transferCheck():开始事务")Threadsleep()Accountaccount=(Account)sessionget(Accountclass,newLong())logwrite("transferCheck():查询到存款余额为:balance="accountgetBalance())Threadsleep()accountsetBalance(accountgetBalance())logwrite("transferCheck():汇入元把存款余额改为:"accountgetBalance())txcommit()当Hibernate执行update语句时可能会抛出StaleObjectExceptionlogwrite("transferCheck():提交事务")Threadsleep()}catch(StaleObjectStateExceptione){if(tx!=){txrollback()}eprintStackTrace()Systemoutprintln("账户信息已被其他事务修改,本事务被撤销请重新开始支票转账事务")logwrite("transferCheck():账户信息已被其他事务修改,本事务被撤销")}PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn利用乐观锁协调并发的取款事务和支票转账事务PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn实现乐观锁的其他方法n如果应用程序是基于已有的数据库而数据库表中不包含代表版本或时间戳的字段Hibernate提供了其他实现乐观锁的办法。把<class>元素的optimisticlock属性设为“all”:<classname="Account"table="ACCOUNTS"optimisticlock="all"dynamicupdate="true">nHibernate会在update语句的where子句中包含Account对象被加载时的所有属性:updateACCOUNTSsetBALANCE=whereID=andNAME='Tom'andBALANCE=''PDF文件使用"pdfFactory"试用版本创建wwwfineprintcomcn

职业精品

(汽车)产品营销策划书范文.doc

HH牙膏营销方案策划书.doc

加班管理人力资源考勤管理系统方案.doc

物品采购管理制度-正式.doc

用户评论

0/200
    暂无评论
上传我的资料

精彩专题

相关资料换一换

  • JavaTransactionB…

  • SAP Transaction …

  • Transaction_Cost…

  • transaction-logi…

  • SAP_Transaction_…

  • Bitcoin transact…

  • TransactionMemor…

  • transaction risk…

  • 9-1.pdf

  • 9-2.pdf

资料评价:

/ 33
所需积分:1 立即下载

意见
反馈

返回
顶部