中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站備案 身份證廣州seo成功案例

網(wǎng)站備案 身份證,廣州seo成功案例,個(gè)性化定制客戶和網(wǎng)站建設(shè),北京企業(yè)做網(wǎng)站費(fèi)用概念 事務(wù)定義 事務(wù),就是一組操作數(shù)據(jù)庫的動(dòng)作集合。事務(wù)是現(xiàn)代數(shù)據(jù)庫理論中的核心概念之一。如果一組處理步驟或者全部發(fā)生或者一步也不執(zhí)行,我們稱該組處理步驟為一個(gè)事務(wù)。當(dāng)所有的步驟像一個(gè)操作一樣被完整地執(zhí)行,我們稱該事務(wù)被提交?!?article class="baidu_pl">

概念

事務(wù)定義

事務(wù),就是一組操作數(shù)據(jù)庫的動(dòng)作集合。事務(wù)是現(xiàn)代數(shù)據(jù)庫理論中的核心概念之一。如果一組處理步驟或者全部發(fā)生或者一步也不執(zhí)行,我們稱該組處理步驟為一個(gè)事務(wù)。當(dāng)所有的步驟像一個(gè)操作一樣被完整地執(zhí)行,我們稱該事務(wù)被提交。由于其中的一部分或多步執(zhí)行失敗,導(dǎo)致沒有步驟被提交,則事務(wù)必須回滾到最初的系統(tǒng)狀態(tài)。

事務(wù)特點(diǎn)
  • 原子性:一個(gè)事務(wù)中所有對數(shù)據(jù)庫的操作是一個(gè)不可分割的操作序列,要么全做要么全不做
  • 一致性:數(shù)據(jù)不會(huì)因?yàn)槭聞?wù)的執(zhí)行而遭到破壞
  • 隔離性:一個(gè)事務(wù)的執(zhí)行,不受其他事務(wù)的干擾,即并發(fā)執(zhí)行的事務(wù)之間互不干擾
  • 持久性:一個(gè)事務(wù)一旦提交,它對數(shù)據(jù)庫的改變就是永久的。

事務(wù)實(shí)現(xiàn)機(jī)制

Spring為事務(wù)管理提供了豐富的功能支持。Spring 事務(wù)管理分為編程式聲明式的兩種方式。

  • 編程式事務(wù)管理: 編程式事務(wù)管理使用TransactionTemplate或者直接使用底層的 PlatformTransactionManager。對于編程式事務(wù)管理,spring 推薦使用 TransactionTemplate。
  • 聲明式事務(wù)管理: 建立在 AOP 之上的。其本質(zhì)是對方法前后進(jìn)行攔截,然后在目標(biāo)方法開始之前創(chuàng)建或者加入一個(gè)事務(wù),在執(zhí)行完目標(biāo)方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。
  • 聲明式事務(wù)管理不需要入侵代碼,更快捷而且簡單,推薦使用。

聲明式事務(wù)有兩種方式:

  • 一種是在配置文件(xml)中做相關(guān)的事務(wù)規(guī)則聲明(因?yàn)楹苌儆帽疚牟恢v解)
  • 另一種是基于**@Transactional**注解的方式。注釋配置是目前流行的使用方式,推薦使用。

在應(yīng)用系統(tǒng)調(diào)用聲明了 @Transactional 的目標(biāo)方法時(shí),Spring Framework 默認(rèn)使用 AOP 代理,在代碼運(yùn)行時(shí)生成一個(gè)代理對象,根據(jù) @Transactional 的屬性配置信息,這個(gè)代理對象決定該聲明 @Transactional 的目標(biāo)方法是否由攔截器 TransactionInterceptor 來使用攔截,在 TransactionInterceptor 攔截時(shí),會(huì)在目標(biāo)方法開始執(zhí)行之前創(chuàng)建并加入事務(wù),并執(zhí)行目標(biāo)方法的邏輯,最后根據(jù)執(zhí)行情況是否出現(xiàn)異常,利用抽象事務(wù)管理器 AbstractPlatformTransactionManager 操作數(shù)據(jù)源 DataSource 提交或回滾事務(wù)。

Spring AOP 代理有 CglibAopProxy 和 JdkDynamicAopProxy 兩種,以 CglibAopProxy 為例,對于 CglibAopProxy,需要調(diào)用其內(nèi)部類的 DynamicAdvisedInterceptor 的 intercept 方法。對于 JdkDynamicAopProxy,需要調(diào)用其 invoke 方法。

開啟事務(wù)

注解 @Transactional 的使用
注解 @Transactional 常用配置

參 數(shù) 名 稱

功 能 描 述

readOnly

用于設(shè)置當(dāng)前事務(wù)是否為只讀事務(wù),設(shè)置為 true 表示只讀,false 則表示可讀寫,默認(rèn)值為 false。例如:@Transactional(readOnly=true)

rollbackFor

用于設(shè)置需要進(jìn)行回滾的異常類數(shù)組,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí),則進(jìn)行事務(wù)回滾。例如:指定單一異常類:@Transactional(rollbackFor=RuntimeException.class);指定多個(gè)異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class})

transactionManager / value

多個(gè)事務(wù)管理器托管在 Spring 容器中時(shí),指定事務(wù)管理器的 bean 名稱

rollbackForClassName

用于設(shè)置需要進(jìn)行回滾的異常類名稱數(shù)組,當(dāng)方法中拋出指定異常名稱數(shù)組中的異常時(shí),則進(jìn)行事務(wù)回滾。例如:指定單一異常類名稱 @Transactional(rollbackForClassName=”RuntimeException”) 指定多個(gè)異常類名稱:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})

noRollbackFor

用于設(shè)置不需要進(jìn)行回滾的異常類數(shù)組,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí),不進(jìn)行事務(wù)回滾。例如:指定單一異常類:@Transactional(noRollbackFor=RuntimeException.class) 指定多個(gè)異常類:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})

noRollbackForClassName

用于設(shè)置不需要進(jìn)行回滾的異常類名稱數(shù)組,當(dāng)方法中拋出指定異常名稱數(shù)組中的異常時(shí),不進(jìn)行事務(wù)回滾。例如:指定單一異常類名稱:@Transactional(noRollbackForClassName=”RuntimeException”) 指定多個(gè)異常類名稱:@Transactional(noRollbackForClassName={“RuntimeException”, ”Exception”})

propagation

用于設(shè)置事務(wù)的傳播行為。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly=true)

isolation

用于設(shè)置底層數(shù)據(jù)庫的事務(wù)隔離級(jí)別,事務(wù)隔離級(jí)別用于處理多事務(wù)并發(fā)的情況,通常使用數(shù)據(jù)庫的默認(rèn)隔離級(jí)別即可,基本不需要進(jìn)行設(shè)置

timeout

該屬性用于設(shè)置事務(wù)的超時(shí)秒數(shù),默認(rèn)值為 - 1 表示永不超時(shí)
事物超時(shí)設(shè)置:@Transactional(timeout=30) ,設(shè)置為 30 秒

Propagation 的屬性(事務(wù)的傳播行為)

例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)

Propagation 屬性

含義

REQUIRED

默認(rèn)值 在有 transaction 狀態(tài)下執(zhí)行;如當(dāng)前沒有 transaction,則創(chuàng)建新的 transaction;

SUPPORTS

如當(dāng)前有 transaction,則在 transaction 狀態(tài)下執(zhí)行;如果當(dāng)前沒有 transaction,在無 transaction 狀態(tài)下執(zhí)行;

MANDATORY

必須在有 transaction 狀態(tài)下執(zhí)行,如果當(dāng)前沒有 transaction,則拋出異常 IllegalTransactionStateException;

REQUIRES_NEW

創(chuàng)建新的 transaction 并執(zhí)行;如果當(dāng)前已有 transaction,則將當(dāng)前 transaction 掛起;

NOT_SUPPORTED

在無 transaction 狀態(tài)下執(zhí)行;如果當(dāng)前已有 transaction,則將當(dāng)前 transaction 掛起;

NEVER

在無 transaction 狀態(tài)下執(zhí)行;如果當(dāng)前已有 transaction,則拋出異常 IllegalTransactionStateException。

事務(wù) 5 種隔離級(jí)別

例如:@Transactional(isolation = Isolation.READ_COMMITTED)

隔離級(jí)別

含義

DEFAULT

這是一個(gè) PlatfromTransactionManager 默認(rèn)的隔離級(jí)別,使用數(shù)據(jù)庫默認(rèn)的事務(wù)隔離級(jí)別另外四個(gè)與 JDBC 的隔離級(jí)別相對應(yīng);

READ_UNCOMMITTED

最低的隔離級(jí)別。事實(shí)上我們不應(yīng)該稱其為隔離級(jí)別,因?yàn)樵谑聞?wù)完成前,其他事務(wù)可以看到該事務(wù)所修改的數(shù)據(jù)。而在其他事務(wù)提交前,該事務(wù)也可以看到其他事務(wù)所做的修改。可能導(dǎo)致臟,幻,不可重復(fù)讀

READ_COMMITTED

大多數(shù)數(shù)據(jù)庫的默認(rèn)級(jí)別。在事務(wù)完成前,其他事務(wù)無法看到該事務(wù)所修改的數(shù)據(jù)。遺憾的是,在該事務(wù)提交后,你就可以查看其他事務(wù)插入或更新的數(shù)據(jù)。這意味著在事務(wù)的不同點(diǎn)上,如果其他事務(wù)修改了數(shù)據(jù),你就會(huì)看到不同的數(shù)據(jù)。可防止臟讀,但幻讀和不可重復(fù)讀仍可以發(fā)生。

REPEATABLE_READ

比 ISOLATION_READ_COMMITTED 更嚴(yán)格,該隔離級(jí)別確保如果在事務(wù)中查詢了某個(gè)數(shù)據(jù)集,你至少還能再次查詢到相同的數(shù)據(jù)集,即使其他事務(wù)修改了所查詢的數(shù)據(jù)。然而如果其他事務(wù)插入了新數(shù)據(jù),你就可以查詢到該新插入的數(shù)據(jù)??煞乐古K讀,不可重復(fù)讀,但幻讀仍可能發(fā)生。

SERIALIZABLE

完全服從 ACID 的隔離級(jí)別,確保不發(fā)生臟讀、不可重復(fù)讀和幻影讀。這在所有隔離級(jí)別中也是最慢的,因?yàn)樗ǔJ峭ㄟ^完全鎖定當(dāng)前事務(wù)所涉及的數(shù)據(jù)表來完成的。代價(jià)最大、可靠性最高的隔離級(jí)別,所有的事務(wù)都是按順序一個(gè)接一個(gè)地執(zhí)行。避免所有不安全讀取。

使用注意事項(xiàng)(防止事務(wù)失效)
  • 在具體的類(或類的方法)上使用 @Transactional 注解,而不要使用在類所要實(shí)現(xiàn)的任何接口上。

  • **@Transactional 注解應(yīng)該只被應(yīng)用在 public 修飾的方法上。**如果你在 protected、private 或者 package-visible 的方法上使用 該注解,它也不會(huì)報(bào)錯(cuò)(IDEA 會(huì)有提示), 但事務(wù)并沒有生效。

  • 被外部調(diào)用的公共方法 A 有兩個(gè)進(jìn)行了數(shù)據(jù)操作的子方法 B 和子方法 C 的事務(wù)注解說明:

    • 被外部調(diào)用的公共方法 A 未聲明事務(wù) @Transactional,子方法 B 和 C 若是其他類的方法且各自聲明事務(wù),則事務(wù)由子方法 B 和 C 各自控制

    • 被外部調(diào)用的公共方法 A 未聲明事務(wù) @Transactional,子方法 B 和 C 若是本類的方法,則無論子方法 B 和 C 是否聲明事務(wù),事務(wù)均不會(huì)生效

    • 被外部調(diào)用的公共方法 A 聲明事務(wù) @Transactional,無論子方法 B 和 C 是不是本類的方法,無論子方法 B 和 C 是否聲明事務(wù),事務(wù)均由公共方法 A 控制

    • 被外部調(diào)用的公共方法 A 聲明事務(wù) @Transactional,子方法運(yùn)行異常,但運(yùn)行異常被子方法自己try-catch處理了,則事務(wù)回滾是不會(huì)生效的!

      如果想要事務(wù)回滾生效,需要將子方法的事務(wù)控制交給調(diào)用的方法來處理:

      • 方案 1:子方法中不用try-catch處理運(yùn)行異常
      • 方案 2:子方法的 catch 里面將運(yùn)行異常拋出【throw new RuntimeException();】
  • 默認(rèn)情況下,Spring 會(huì)對 unchecked 異常進(jìn)行事務(wù)回滾,也就是默認(rèn)對 RuntimeException() 異?;蚴瞧渥宇愡M(jìn)行事務(wù)回滾。

    如果是 checked 異常則不回滾,例如空指針異常、算數(shù)異常等會(huì)被回滾;文件讀寫、網(wǎng)絡(luò)問題 Spring 就沒法回滾。

    若想對所有異常(包括自定義異常)都起作用,注解上面需配置異常類型:@Transactional(rollbackFor = Exception.class

  • 數(shù)據(jù)庫要支持事務(wù),如果是 mysql,要使用 innodb 引擎,myisam 不支持事務(wù)

  • 事務(wù) @Transactional 由 spring 控制時(shí),它會(huì)在拋出異常的時(shí)候進(jìn)行回滾。如果自己使用 try-catch 捕獲處理了,是不生效的。如果想事務(wù)生效可以進(jìn)行手動(dòng)回滾或者在 catch 里面將異常拋出【throw new RuntimeException();】

    • 方案一:手動(dòng)拋出運(yùn)行時(shí)異常(缺陷是不能在 catch 代碼塊自定義返回值)

      try{....  }catch(Exception e){logger.error("",e);throw new RuntimeException(e);}
      
    • 方案二:手動(dòng)進(jìn)行回滾【 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 】

      try{...}catch(Exception e){log.error("fail",e);TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();return false;}
      
  • @Transactional 可以放在 Controller 下面直接起作用,看到網(wǎng)上好多同學(xué)說要放到 @Component 下面或者 @Service 下面,經(jīng)過試驗(yàn),可以不用放在這兩個(gè)下面也起作用。

  • @Transactional 引入包問題,它有兩個(gè)包:

    import javax.transaction.Transactional; 
    // 和
    import org.springframework.transaction.annotation.Transactional;         // 推薦
    

    這兩個(gè)都可以用,對比了一下他們兩個(gè)的方法和屬性,發(fā)現(xiàn)后面的比前面的強(qiáng)大。建議使用后面的。

使用場景
自動(dòng)回滾

直接拋出,不 try/catch

@Override
@Transactional(rollbackFor = Exception.class)
public Object submitOrder() throws Exception {  success();  //假如exception這個(gè)操作數(shù)據(jù)庫的方法會(huì)拋出異常,方法success()對數(shù)據(jù)庫的操作會(huì)回滾。 exception(); return ApiReturnUtil.success();
}
手動(dòng)回滾

進(jìn)行 try/catch,回滾并拋出

@Override
@Transactional(rollbackFor = Exception.class)
public Object submitOrder (){  success();  try {  exception(); } catch (Exception e) {  e.printStackTrace();     // 手動(dòng)回滾事務(wù)TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();return ApiReturnUtil.error();}  return ApiReturnUtil.success();
}
回滾部分異常

使用【Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint(); 】設(shè)置回滾點(diǎn)。

使用【TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);】回滾到 savePoint。

@Override
@Transactional(rollbackFor = Exception.class)
public Object submitOrder (){  success();  //只回滾以下異常,Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();try {  exception(); } catch (Exception e) {  e.printStackTrace();     // 手工回滾事務(wù)TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);return ApiReturnUtil.error();}  return ApiReturnUtil.success();
}
手動(dòng)創(chuàng)建、提交、回滾事務(wù)

PlatformTransactionManager 這個(gè)接口中定義了三個(gè)方法 getTransaction 創(chuàng)建事務(wù),commit 提交事務(wù),rollback 回滾事務(wù)。它的實(shí)現(xiàn)類是 AbstractPlatformTransactionManager。

@Autowired
priDataSourceTransactionManager dataSourceTransactionManager;
@Autowired
TransactionDefinition transactionDefinition;// 手動(dòng)創(chuàng)建事務(wù)
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);// 手動(dòng)提交事務(wù)
dataSourceTransactionManager.commit(transactionStatus);// 手動(dòng)回滾事務(wù)。(最好是放在catch 里面,防止程序異常而事務(wù)一直卡在哪里未提交)
dataSourceTransactionManager.rollback(transactionStatus);
PlatformTransactionManager 手動(dòng)提交事務(wù),設(shè)置隔離級(jí)別
@Autowired
private PlatformTransactionManager transactionManager;public void test() {DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatus transactionStatus = transactionManager.getTransaction(defaultTransactionDefinition);try {// 數(shù)據(jù)庫操作 //提交事務(wù)transactionManager.commit(transactionStatus);} catch (Exception e) {log.error("xxxx", e);//回滾事務(wù)transactionManager.rollback(transactionStatus);}
}

事務(wù)失效不回滾的原因及解決方案

異常被捕獲導(dǎo)致事務(wù)失效

在 spring boot 中,使用事務(wù)非常簡單,直接在方法上面加入 @Transactional 就可以實(shí)現(xiàn)。

@GetMapping("delete")
@ResponseBody
@Transactional    
public void delete(@RequestParam("id") int id) {       try {          //delete countrythis.repository.delete(id);         if(id == 1){              throw Exception("測試事務(wù)");}           //delete citythis.repository.deleteByCountryId(id);}catch (Exception e){logger.error("delete false:" + e.getMessage());        }
}

發(fā)現(xiàn)事務(wù)不回滾,即 this.repository.delete(id);成功把數(shù)據(jù)刪除了。

原因:

默認(rèn) spring 事務(wù)只在發(fā)生未被捕獲的 RuntimeException 時(shí)才回滾。

spring aop 異常捕獲原理:被攔截的方法需顯式拋出異常,并不能經(jīng)任何處理,這樣 aop 代理才能捕獲到方法的異常,才能進(jìn)行回滾,默認(rèn)情況下 aop 只捕獲 RuntimeException 的異常,但可以通過配置來捕獲特定的異常并回滾。

換句話說在 service 的方法中不使用 try catch 或者在 catch 中最后加上 throw new RuntimeExcetpion() 拋出運(yùn)行異常,這樣程序異常時(shí)才能被 aop 捕獲進(jìn)而回滾。

解決方案:

<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>4.3.2.RELEASE</version></dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.9</version>
</dependency><plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.9</version>
<configuration><showWeaveInfo>true</showWeaveInfo><aspectLibraries><aspectLibrary><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId></aspectLibrary></aspectLibraries>
</configuration><executions>
<execution><goals><goal>compile</goal><goal>test-compile</goal></goals>
</execution>
</executions>
</plugin>
解決方案

方案 1、在類上(或者最外層的公共方法)加事務(wù)

@Service
@Slf4j
public class MyTransactional {// 最外層公共方法。自動(dòng)回滾事務(wù)方式,insertOrder()方法報(bào)錯(cuò)后事務(wù)回滾,且線程中止,后續(xù)邏輯無法執(zhí)行@Transactionalpublic void test1() {this.insertOrder();System.out.println("11111111111111111");}// 最外層公共方法。手動(dòng)回滾事務(wù)方式,insertOrder()方法報(bào)錯(cuò)后事務(wù)回滾,可以繼續(xù)執(zhí)行后續(xù)邏輯@Transactionalpublic void test2() {try {  insertOrder();} catch (Exception e) {  log.error("faild to ...", e);// 手動(dòng)回滾事務(wù)TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();// 其他操作}// 其他操作}// 進(jìn)行數(shù)據(jù)庫操作的方法(private 或 public 均可)private void insertOrder() {//insert log info//insertOrder//updateAccount}
}

方案 2、使用 AspectJ 取代 Spring AOP 代理

上面的兩個(gè)問題 @Transactional 注解只應(yīng)用到 public 方法和自調(diào)用問題,是由于使用 Spring AOP 代理造成的。為解決這兩個(gè)問題,可以使用 AspectJ 取代 Spring AOP 代理。

需要將下面的 AspectJ 信息添加到 xml 配置信息中。

AspectJ 的 xml 配置信息

<tx:annotation-driven mode="aspectj" />
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property  />
</bean>
</bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf"><property  />
</bean>

同時(shí)在 Maven 的 pom 文件中加入 spring-aspects 和 aspectjrt 的 dependency 以及 aspectj-maven-plugin。

AspectJ 的 pom 配置信息

其他

事務(wù)提交方式

默認(rèn)情況下,數(shù)據(jù)庫處于自動(dòng)提交模式。每一條語句處于一個(gè)單獨(dú)的事務(wù)中,在這條語句執(zhí)行完畢時(shí),如果執(zhí)行成功則隱式的提交事務(wù),如果執(zhí)行失敗則隱式的回滾事務(wù)。

對于正常的事務(wù)管理,是一組相關(guān)的操作處于一個(gè)事務(wù)之中,因此必須關(guān)閉數(shù)據(jù)庫的自動(dòng)提交模式。不過,這個(gè)我們不用擔(dān)心,spring 會(huì)將底層連接的【自動(dòng)提交特性】設(shè)置為 false 。也就是在使用 spring 進(jìn)行事務(wù)管理的時(shí)候,spring 會(huì)將【是否自動(dòng)提交】設(shè)置為 false,等價(jià)于 JDBC 中的 connection.setAutoCommit(false); ,在執(zhí)行完之后在進(jìn)行提交 connection.commit(); 。

事務(wù)回滾規(guī)則

指示 spring 事務(wù)管理器回滾一個(gè)事務(wù)的推薦方法是在當(dāng)前事務(wù)的上下文內(nèi)拋出異常。spring 事務(wù)管理器會(huì)捕捉任何未處理的異常,然后依據(jù)規(guī)則決定是否回滾拋出異常的事務(wù)。

默認(rèn)配置下,spring 只有在拋出的異常為運(yùn)行時(shí) unchecked 異常時(shí)才回滾該事務(wù),也就是拋出的異常為 RuntimeException 的子類 (Errors 也會(huì)導(dǎo)致事務(wù)回滾),而拋出 checked 異常則不會(huì)導(dǎo)致事務(wù)回滾。

可以明確的配置在拋出那些異常時(shí)回滾事務(wù),包括 checked 異常。也可以明確定義那些異常拋出時(shí)不回滾事務(wù)。

事務(wù)并發(fā)會(huì)產(chǎn)生的問題

術(shù)語

含義

臟讀

A 事務(wù)讀取到了 B 事務(wù)還未提交的數(shù)據(jù),如果 B 未提交的事務(wù)回滾了,那么 A 事務(wù)讀取的數(shù)據(jù)就是無效的,這就是數(shù)據(jù)臟讀

不可重復(fù)讀

在同一個(gè)事務(wù)中,多次讀取同一數(shù)據(jù)返回的結(jié)果不一致,這是由于讀取事務(wù)在進(jìn)行操作的過程中,如果出現(xiàn)更新事務(wù),它必須等待更新事務(wù)執(zhí)行成功提交完成后才能繼續(xù)讀取數(shù)據(jù),這就導(dǎo)致讀取事務(wù)在前后讀取的數(shù)據(jù)不一致的狀況出現(xiàn)

幻讀

A 事務(wù)讀取了幾行記錄后,B 事務(wù)插入了新數(shù)據(jù),并且提交了插入操作,在后續(xù)操作中 A 事務(wù)就會(huì)多出幾行原本不存在的數(shù)據(jù),就像 A 事務(wù)出現(xiàn)幻覺,這就是幻讀

第一類丟失更新

沒有事務(wù)隔離的情況下,兩個(gè)事務(wù)都同時(shí)更新一行數(shù)據(jù),但是第二個(gè)事務(wù)卻中途失敗退出, 導(dǎo)致對數(shù)據(jù)的兩個(gè)修改都失效了。

例如:

張三的工資為 5000,事務(wù) A 中獲取工資為 5000,事務(wù) B 獲取工資為 5000,匯入 100,并提交數(shù)據(jù)庫,工資變?yōu)?5100;

與此同時(shí),事務(wù)B正在讀取張三的工資,讀取到張三的工資為8000。隨后,事務(wù)A發(fā)生異常,回滾了事務(wù),張三的工資又回滾為5000。最后,事務(wù)B讀取到的張三工資為8000的數(shù)據(jù)即為臟數(shù)據(jù),事務(wù)B做了一次臟讀。
臟讀

臟讀就是指當(dāng)一個(gè)事務(wù)正在訪問數(shù)據(jù),并且對數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中,這時(shí),另外一個(gè)事務(wù)也訪問這個(gè)數(shù)據(jù),然后使用了這個(gè)數(shù)據(jù)。

例如:

張三的工資為 5000,事務(wù) A 中把他的工資改為 8000,但事務(wù) A 尚未提交。

與此同時(shí),事務(wù)B正在讀取張三的工資,讀取到張三的工資為8000。隨后,事務(wù)A發(fā)生異常,回滾了事務(wù),張三的工資又回滾為5000。最后,事務(wù)B讀取到的張三工資為8000的數(shù)據(jù)即為臟數(shù)據(jù),事務(wù)B做了一次臟讀。
不可重復(fù)讀

是指在一個(gè)事務(wù)內(nèi),多次讀同一數(shù)據(jù)。在這個(gè)事務(wù)還沒有結(jié)束時(shí),另外一個(gè)事務(wù)也訪問該同一數(shù)據(jù)。那么,在第一個(gè)事務(wù)中的兩次讀數(shù)據(jù)之間,由于第二個(gè)事務(wù)的修改,那么第一個(gè)事務(wù)兩次讀到的的數(shù)據(jù)可能是不一樣的。這樣就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的,因此稱為是不可重復(fù)讀。

例如:

在事務(wù) A 中,讀取到張三的工資為 5000,操作沒有完成,事務(wù)還沒提交。
  與此同時(shí),事務(wù) B 把張三的工資改為 8000,并提交了事務(wù)。
  隨后,在事務(wù) A 中,再次讀取張三的工資,此時(shí)工資變?yōu)?8000。在一個(gè)事務(wù)中前后兩次讀取的結(jié)果并不致,導(dǎo)致了不可重復(fù)讀。

第二類丟失更新

不可重復(fù)讀的特例。

有兩個(gè)并發(fā)事務(wù)同時(shí)讀取同一行數(shù)據(jù),然后其中一個(gè)對它進(jìn)行修改提交,而另一個(gè)也進(jìn)行了修改提交。這就會(huì)造成第一次寫操作失效。

例如:

在事務(wù) A 中,讀取到張三的存款為 5000,操作沒有完成,事務(wù)還沒提交。
  與此同時(shí),事務(wù) B 存入 1000,把張三的存款改為 6000,并提交了事務(wù)。
  隨后,在事務(wù) A 中,存儲(chǔ) 500,把張三的存款改為 5500,并提交了事務(wù),這樣事務(wù) A 的更新覆蓋了事務(wù) B 的更新。

幻讀

是指當(dāng)事務(wù)不是獨(dú)立執(zhí)行時(shí)發(fā)生的一種現(xiàn)象,例如第一個(gè)事務(wù)對一個(gè)表中的數(shù)據(jù)進(jìn)行了修改,這種修改涉及到表中的全部數(shù)據(jù)行。同時(shí),第二個(gè)事務(wù)也修改這個(gè)表中的數(shù)據(jù),這種修改是向表中插入一行新數(shù)據(jù)。那么,以后就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺一樣。

例如:

目前工資為 5000 的員工有 10 人,事務(wù) A 讀取到所有的工資為 5000 的人數(shù)為 10 人。
  此時(shí),事務(wù) B 插入一條工資也為 5000 的記錄。
  這時(shí),事務(wù) A 再次讀取工資為 5000 的員工,記錄為 11 人。此時(shí)產(chǎn)生了幻讀。

不可重復(fù)讀和幻讀的區(qū)別

不可重復(fù)讀的重點(diǎn)是修改,同樣的條件,你讀取過的數(shù)據(jù),再次讀取出來發(fā)現(xiàn)值不一樣了

幻讀的重點(diǎn)在于新增或者刪除,同樣的條件,第 1 次和第 2 次讀出來的記錄數(shù)不一樣

http://m.risenshineclean.com/news/59834.html

相關(guān)文章:

  • 福鼎建設(shè)局網(wǎng)站首頁最簡單的網(wǎng)頁制作
  • 網(wǎng)站怎么做微信登錄四川網(wǎng)站制作
  • 網(wǎng)站建設(shè)南京關(guān)鍵詞seo價(jià)格
  • 桃江縣建設(shè)局網(wǎng)站凱里seo排名優(yōu)化
  • 什么網(wǎng)站做電腦系統(tǒng)好免費(fèi)網(wǎng)絡(luò)推廣軟件
  • 做農(nóng)業(yè)種子的網(wǎng)站湖南網(wǎng)站建設(shè)效果
  • 桑拿網(wǎng)站橫幅廣告怎么做seo工資多少
  • 西安網(wǎng)站制作怎么做網(wǎng)站推廣
  • 建設(shè)網(wǎng)站找哪里怎么分析一個(gè)網(wǎng)站seo
  • 中國網(wǎng)站模板免費(fèi)下載廣東整治互聯(lián)網(wǎng)霸王條款
  • 做盜版系統(tǒng)網(wǎng)站會(huì)不會(huì)百度識(shí)圖掃一掃
  • pc網(wǎng)站開發(fā)制作蘇州優(yōu)化排名seo
  • 手機(jī)端頁面模板山東seo網(wǎng)頁優(yōu)化外包
  • 內(nèi)地網(wǎng)站用香港服務(wù)器怎么營銷一個(gè)產(chǎn)品
  • 免費(fèi)做房產(chǎn)網(wǎng)站有哪些網(wǎng)絡(luò)推廣的公司更可靠
  • wordpress無法尋找圖像優(yōu)化的含義是什么
  • 深圳橫崗做網(wǎng)站上海網(wǎng)站推廣優(yōu)化
  • 佛山外貿(mào)網(wǎng)站制作外貿(mào)推廣平臺(tái)哪個(gè)好
  • 做網(wǎng)站需要哪些資料佛山做優(yōu)化的網(wǎng)絡(luò)公司
  • 用vs2012做網(wǎng)站首頁關(guān)鍵詞分布中對seo有危害的
  • 同樣也是做嚴(yán)選的網(wǎng)站php視頻轉(zhuǎn)碼
  • wordpress twenty fourteen主題做的演示網(wǎng)站百度視頻排名優(yōu)化
  • 俄羅斯注冊公司多少錢seo網(wǎng)站推廣技術(shù)
  • 江夏區(qū)做網(wǎng)站西安網(wǎng)站建設(shè)方案優(yōu)化
  • 做網(wǎng)站數(shù)據(jù)庫及相關(guān)配置小程序搭建
  • 做淘寶客如何建自己的網(wǎng)站營銷說白了就是干什么的
  • 做網(wǎng)站運(yùn)營難嗎吸引人的微信軟文
  • 東莞哪里的網(wǎng)站建設(shè)效果好注冊網(wǎng)站免費(fèi)注冊
  • 華為網(wǎng)站開發(fā)流程怎么seo快速排名
  • 天津做網(wǎng)站要多少錢北京seo服務(wù)銷售