日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从@Transactional看事务的传播和隔离

發(fā)布時(shí)間:2024/9/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从@Transactional看事务的传播和隔离 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1. transactionManager 當(dāng)在配置文件中有多個(gè)TransactionManager,可以用該屬性指定使用哪個(gè)事務(wù)管理器
    • 2. 事務(wù)的傳播行為(propagation) ,默認(rèn)值為REQUIRED
    • 3.事務(wù)的隔離( isolation)
    • 4. timeout 事務(wù)的超時(shí)時(shí)間 默認(rèn)值為-1. 超時(shí)自動回滾
    • 5. readOnly 是否為只讀事務(wù),默認(rèn)值為false,即非只讀事務(wù)
    • 6. rollbackFor 指定能夠觸發(fā)事務(wù)回滾的異常類型 noRollbackFor 指定那些異常類型不回滾事務(wù)
  • 事務(wù)失效的場景

spring如何處理事務(wù)呢?下面是個(gè)偽代碼示意:

begin Transactional;try{//TODOcommit;}catch (Throwable e){if(e屬于該提交的(即noRollbackFor指定)的異常類型){commit;}else {rollback;}}

1. transactionManager 當(dāng)在配置文件中有多個(gè)TransactionManager,可以用該屬性指定使用哪個(gè)事務(wù)管理器

如果要配置全局事務(wù)管理,參考這篇文章全局性事務(wù)控制如何在springboot中配置

2. 事務(wù)的傳播行為(propagation) ,默認(rèn)值為REQUIRED

  • Propagation.REQUIRED
    默認(rèn)傳播行為 如果有事務(wù)那么加入此事務(wù),沒有就新建一個(gè)事務(wù)
/*** Support a current transaction, create a new one if none exists.* <p>This is the default setting of a transaction annotation.*/
  • Propagation.SUPPORTS
    如果其他bean調(diào)用這個(gè)方法,在其他bean中聲明了事務(wù)那么久加入事務(wù),如果其他bean中沒有聲明事務(wù)就不用事務(wù)
/*** Support a current transaction, execute non-transactionally if none exists.* <p>Note: For transaction managers with transaction synchronization,* PROPAGATION_SUPPORTS is slightly different from no transaction at all,* as it defines a transaction scope that synchronization will apply for.* As a consequence, the same resources (JDBC Connection, Hibernate Session, etc)* will be shared for the entire specified scope. Note that this depends on* the actual synchronization configuration of the transaction manager.*/
  • Propagation.REQUIRES_NEW
    不管是否存在事務(wù),都創(chuàng)建一個(gè)新的事務(wù)。如果已經(jīng)存在一個(gè)事務(wù)就停止他
/*** Create a new transaction, suspending the current transaction if one exists.* <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box* on all transaction managers. This in particular applies to* {@link org.springframework.transaction.jta.JtaTransactionManager},* which requires the {@code javax.transaction.TransactionManager} to be* made available it to it (which is server-specific in standard Java EE).* <p>A {@code PROPAGATION_REQUIRES_NEW} scope always defines its own* transaction synchronizations. Existing synchronizations will be suspended* and resumed appropriately.*/
  • Propagation.NOT_SUPPORTED
    不為這個(gè)方法開啟事務(wù)
/*** Do not support a current transaction; rather always execute non-transactionally.* <p><b>NOTE:</b> Actual transaction suspension will not work out-of-the-box* on all transaction managers. This in particular applies to* {@link org.springframework.transaction.jta.JtaTransactionManager},* which requires the {@code javax.transaction.TransactionManager} to be* made available it to it (which is server-specific in standard Java EE).* <p>Note that transaction synchronization is <i>not</i> available within a* {@code PROPAGATION_NOT_SUPPORTED} scope. Existing synchronizations* will be suspended and resumed appropriately.*/
  • Propagation.MANDATORY
    必須當(dāng)前存在事務(wù),否則拋出異常
/*** Support a current transaction, throw an exception if none exists.* Analogous to EJB transaction attribute of the same name.*/
  • Propagation.NEVER
    必須當(dāng)前沒有事務(wù),否則拋出異常,與Propagation.MANDATORY相反
/*** Execute non-transactionally, throw an exception if a transaction exists.*/
  • Propagation.NESTED
    如果當(dāng)前存在事務(wù),則在嵌套事務(wù)中執(zhí)行,類似于ROPAGATION_REQUIRED
/*** Execute within a nested transaction if a current transaction exists,* behave like PROPAGATION_REQUIRED else. There is no analogous feature in EJB.* <p>Note: Actual creation of a nested transaction will only work on specific* transaction managers. Out of the box, this only applies to the JDBC*/

嵌套事務(wù)中發(fā)生異常會回滾到savePoint,不對主事務(wù)之前的操作產(chǎn)生影響,但提交還要依賴主事務(wù)的成功。

3.事務(wù)的隔離( isolation)

  • DEFAULT使用數(shù)據(jù)庫默認(rèn)的級別
    postgres數(shù)據(jù)庫的默認(rèn)隔離級別是已提交讀 ,MySQL的默認(rèn)事務(wù)隔離級別是可重復(fù)讀。
  • READ_UNCOMMITTED 未提交讀
A constant indicating that dirty reads, non-repeatable reads and phantom reads* can occur. This level allows a row changed by one transaction to be read by* another transaction before any changes in that row have been committed* (a "dirty read"). If any of the changes are rolled back, the second* transaction will have retrieved an invalid row.
  • READ_COMMITTED 已提交讀
A constant indicating that dirty reads are prevented; non-repeatable reads* and phantom reads can occur. This level only prohibits a transaction* from reading a row with uncommitted changes in it.
  • REPEATABLE_READ 可重復(fù)讀
A constant indicating that dirty reads and non-repeatable reads are* prevented; phantom reads can occur. This level prohibits a transaction* from reading a row with uncommitted changes in it, and it also prohibits* the situation where one transaction reads a row, a second transaction* alters the row, and the first transaction rereads the row, getting* different values the second time (a "non-repeatable read").
  • SERIALIZABLE 串行化
A constant indicating that dirty reads, non-repeatable reads and phantom* reads are prevented. This level includes the prohibitions in* {@code ISOLATION_REPEATABLE_READ} and further prohibits the situation* where one transaction reads all rows that satisfy a {@code WHERE}* condition, a second transaction inserts a row that satisfies that* {@code WHERE} condition, and the first transaction rereads for the* same condition, retrieving the additional "phantom" row in the second read.

幻讀和不可重復(fù)讀相似容易混淆,幻讀指的是第一個(gè)事務(wù)相同查詢條件的查詢行數(shù),另一個(gè)事務(wù)增加或刪除了某行(inserts a row),導(dǎo)致第一個(gè)事務(wù)兩次查詢的結(jié)果不同。不可重復(fù)讀指的是另一個(gè)事務(wù)修改( alters the row)了某行的數(shù)據(jù)。

隔離和鎖是不同的東西,隔離不是靠鎖實(shí)現(xiàn),是根據(jù)對數(shù)據(jù)的監(jiān)控實(shí)現(xiàn)的,相比鎖會回滾事務(wù)。

4. timeout 事務(wù)的超時(shí)時(shí)間 默認(rèn)值為-1. 超時(shí)自動回滾

如果事務(wù)超過時(shí)間限制還沒完成,就會回滾。
從方法執(zhí)行開始計(jì)算。每個(gè)sql執(zhí)行前檢查一次是否超時(shí),方法全部執(zhí)行完畢后不檢查是否超時(shí)。即設(shè)置事務(wù)超時(shí)為10秒,即使整個(gè)方法耗時(shí)20秒也不一定超時(shí)。

假設(shè)事務(wù)超時(shí)時(shí)間設(shè)置為2秒;假設(shè)sql執(zhí)行時(shí)間為1秒;
如下調(diào)用是事務(wù)不超時(shí)的

public void testTimeout() throws InterruptedException { System.out.println(System.currentTimeMillis()); JdbcTemplate jdbcTemplate = new JdbcTemplate(ds); jdbcTemplate.execute(" update test set hobby = hobby || '1'"); System.out.println(System.currentTimeMillis()); Thread.sleep(3000L); }

而如下事務(wù)超時(shí)是起作用的:

public void testTimeout() throws InterruptedException { Thread.sleep(3000L); System.out.println(System.currentTimeMillis()); JdbcTemplate jdbcTemplate = new JdbcTemplate(ds); jdbcTemplate.execute(" update test set hobby = hobby || '1'"); System.out.println(System.currentTimeMillis()); }

參考博客

5. readOnly 是否為只讀事務(wù),默認(rèn)值為false,即非只讀事務(wù)

注意 在只讀事務(wù)中修改數(shù)據(jù)庫是會報(bào)錯(cuò)的!

6. rollbackFor 指定能夠觸發(fā)事務(wù)回滾的異常類型 noRollbackFor 指定那些異常類型不回滾事務(wù)

事務(wù)失效的場景

  • 應(yīng)用在非public方法上
  • 同一個(gè)類中方法的調(diào)用
  • 數(shù)據(jù)庫引擎不支持事務(wù),如innodb支持事務(wù),而myisam就不支持事務(wù)
  • 沒有指定rollbackFor那些異常回滾時(shí),spring默認(rèn)的是運(yùn)行時(shí)異常和error,如果不屬于這些異常也就不會觸發(fā)事務(wù)回滾。或者異常被catch掉了也不會觸發(fā)事務(wù)回滾
  • 傳播機(jī)制設(shè)置為非事務(wù)方式
  • 總結(jié)

    以上是生活随笔為你收集整理的从@Transactional看事务的传播和隔离的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。