日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Spring事務(wù)超時到底是怎么回事?

來源: 責(zé)編: 時間:2023-10-13 14:36:35 306觀看
導(dǎo)讀環(huán)境:Spring5.3.23 Spring事務(wù)超時是指一個事務(wù)在執(zhí)行中最長的允許時間。如果事務(wù)在超時時間內(nèi)未能完成,則會自動回滾。超時時間可以通過設(shè)置來控制,以確保事務(wù)在規(guī)定的時間內(nèi)完成或回滾,避免數(shù)據(jù)一致性問題。在工作中你

環(huán)境:Spring5.3.23We128資訊網(wǎng)——每日最新資訊28at.com

Spring事務(wù)超時是指一個事務(wù)在執(zhí)行中最長的允許時間。如果事務(wù)在超時時間內(nèi)未能完成,則會自動回滾。超時時間可以通過設(shè)置來控制,以確保事務(wù)在規(guī)定的時間內(nèi)完成或回滾,避免數(shù)據(jù)一致性問題。We128資訊網(wǎng)——每日最新資訊28at.com

在工作中你有配置事務(wù)的超時時間嗎?如何進(jìn)行配置事務(wù)超時時間?We128資訊網(wǎng)——每日最新資訊28at.com

1. 配置事務(wù)超時時間

注解方式:We128資訊網(wǎng)——每日最新資訊28at.com

// 這里單位是s@Transactional(timeout = 2)public void save() {}

編程方式1:We128資訊網(wǎng)——每日最新資訊28at.com

@Resourceprivate PlatformTransactionManager tm ;DefaultTransactionDefinition definition = new DefaultTransactionDefinition();definition.setTimeout(2) ;

編程方式2:We128資訊網(wǎng)——每日最新資訊28at.com

@Resourceprivate PlatformTransactionManager tm ;public void update() {  TransactionTemplate template = new TransactionTemplate(tm) ;  template.setTimeout(2) ;  template.execute(new TransactionCallback<Object>() {    @Override    public Object doInTransaction(TransactionStatus status) {      // ...      return null ;    }  }) ;}

以上3種方式讀可以進(jìn)行事務(wù)超時的設(shè)置,什么情況下才能算是事務(wù)超時呢?We128資訊網(wǎng)——每日最新資訊28at.com

2. 準(zhǔn)備環(huán)境

準(zhǔn)備一張2000w數(shù)據(jù)的表We128資訊網(wǎng)——每日最新資訊28at.com

圖片圖片We128資訊網(wǎng)——每日最新資訊28at.com

表字段信息如下:We128資訊網(wǎng)——每日最新資訊28at.com

圖片圖片We128資訊網(wǎng)——每日最新資訊28at.com

此表除主鍵外沒有任何的索引。We128資訊網(wǎng)——每日最新資訊28at.com

圖片圖片We128資訊網(wǎng)——每日最新資訊28at.com

3. 模擬事務(wù)超時

  • 測試1

統(tǒng)計查詢表的數(shù)據(jù)量,將該操作放到一個事務(wù)中,同時設(shè)置事務(wù)的超時時間。We128資訊網(wǎng)——每日最新資訊28at.com

// 將超時時間設(shè)置為20s@Transactional(timeout = 20)public void query() {  long start = System.currentTimeMillis() ;  jdbcTemplate.execute("select count(*) from p_user") ;  System.out.println("耗時:" + (System.currentTimeMillis() - start) + "毫秒") ;}

執(zhí)行結(jié)果:We128資訊網(wǎng)——每日最新資訊28at.com

耗時:3198毫秒

接下來將超時時間改成3sWe128資訊網(wǎng)——每日最新資訊28at.com

執(zhí)行結(jié)果如下:We128資訊網(wǎng)——每日最新資訊28at.com

13:56:01.425 [main] WARN  c.zaxxer.hikari.pool.ProxyConnection - HikariPool-1 - Connection com.mysql.cj.jdbc.ConnectionImpl@504ecd marked as broken because of SQLSTATE(null), ErrorCode(0)com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request  at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:113)  at com.mysql.cj.jdbc.StatementImpl.checkCancelTimeout(StatementImpl.java:2167)

從異常信息看到拋出了超時異常。這里的超時是sql執(zhí)行的超時,是由我們的驅(qū)動程序拋出的異常。We128資訊網(wǎng)——每日最新資訊28at.com

  • 測試2

模擬其它非數(shù)據(jù)庫操作耗時,而這個是在執(zhí)行數(shù)據(jù)庫操作之前We128資訊網(wǎng)——每日最新資訊28at.com

@Transactional(timeout = 2)public void query() {  long start = System.currentTimeMillis() ;  try {    TimeUnit.SECONDS.sleep(3) ;  } catch (InterruptedException e) {    e.printStackTrace();  }  // 執(zhí)行非常簡單的操作  jdbcTemplate.execute("select 1") ;  System.out.println("耗時:" + (System.currentTimeMillis() - start) + "毫秒") ;}

執(zhí)行結(jié)果:We128資訊網(wǎng)——每日最新資訊28at.com

14:08:44.000 [main] DEBUG o.s.jdbc.core.JdbcTemplate - Executing SQL statement [select 1]Exception in thread "main" org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was Wed Oct 11 14:08:42 CST 2023  at org.springframework.transaction.support.ResourceHolderSupport.checkTransactionTimeout(ResourceHolderSupport.java:155)

拋出了超時異常,而這個異常是由Spring框架拋出的。We128資訊網(wǎng)——每日最新資訊28at.com

  • 測試3

模擬其它非數(shù)據(jù)庫操作耗時,而這個是在執(zhí)行數(shù)據(jù)庫操作之后,適當(dāng)調(diào)整上面的代碼順序We128資訊網(wǎng)——每日最新資訊28at.com

@Transactional(timeout = 2)public void query() {  long start = System.currentTimeMillis() ;  jdbcTemplate.execute("select 1") ;  try {    TimeUnit.SECONDS.sleep(3) ;  } catch (InterruptedException e) {    e.printStackTrace();  }  System.out.println("耗時:" + (System.currentTimeMillis() - start) + "毫秒") ;}

執(zhí)行結(jié)果:We128資訊網(wǎng)——每日最新資訊28at.com

耗時:3015毫秒

程序正常運行We128資訊網(wǎng)——每日最新資訊28at.com

  • 測試4

在測試3的基礎(chǔ)上,最后再次執(zhí)行數(shù)據(jù)庫相關(guān)的操作We128資訊網(wǎng)——每日最新資訊28at.com

@Transactional(timeout = 2)public void query() {  long start = System.currentTimeMillis() ;  jdbcTemplate.execute("select 1") ;  try {    TimeUnit.SECONDS.sleep(3) ;  } catch (InterruptedException e) {    e.printStackTrace();  }  System.out.println("耗時:" + (System.currentTimeMillis() - start) + "毫秒") ;  // 再次執(zhí)行數(shù)據(jù)庫相關(guān)操作  jdbcTemplate.execute("select 1") ;}

執(zhí)行結(jié)果:We128資訊網(wǎng)——每日最新資訊28at.com

耗時:3024毫秒14:14:38.257 [main] DEBUG o.s.jdbc.core.JdbcTemplate - Executing SQL statement [select 1]Exception in thread "main" org.springframework.transaction.TransactionTimedOutException: Transaction timed out: deadline was Wed Oct 11 14:14:37 CST 2023  at org.springframework.transaction.support.ResourceHolderSupport.checkTransactionTimeout(ResourceHolderSupport.java:155)

第一個數(shù)據(jù)庫操作,沒有拋出異常,直到第二個執(zhí)行時拋出了異常。We128資訊網(wǎng)——每日最新資訊28at.com

總結(jié):      事務(wù)方法開始執(zhí)行時就開始計時,在執(zhí)行到數(shù)據(jù)庫操作時判斷當(dāng)前的執(zhí)行時間點是否已經(jīng)超過了設(shè)置的超時時間,如果是則拋出Timeout異常。We128資訊網(wǎng)——每日最新資訊28at.com

4. 事務(wù)超時原理

在開始一個事務(wù)時會在DataSourceTransactionManager#doBegin方法中設(shè)置超時時間We128資訊網(wǎng)——每日最新資訊28at.com

protected void doBegin(Object transaction, TransactionDefinition definition) {  int timeout = determineTimeout(definition);  if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {    // 如果注解@Transactional中設(shè)置了timeout,則設(shè)置超時時間    txObject.getConnectionHolder().setTimeoutInSeconds(timeout);  }}protected int determineTimeout(TransactionDefinition definition) {  if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) {    return definition.getTimeout();  }  return getDefaultTimeout();}

當(dāng)通過JdbcTemplate操作數(shù)據(jù)庫時,還會執(zhí)行如下操作We128資訊網(wǎng)——每日最新資訊28at.com

public class JdbcTemplate {  private <T> T execute(StatementCallback<T> action, boolean closeResources) {    Statement stmt = null;    try {      stmt = con.createStatement();      // 配置Statement對象,這其中會設(shè)置超時時間      applyStatementSettings(stmt);      // ...      return result;    }  }    protected void applyStatementSettings(Statement stmt) throws SQLException {    // ...    // getQueryTimeout方法返回的是當(dāng)前JdbcTemplate對象中設(shè)置d餓超時時間    DataSourceUtils.applyTimeout(stmt, getDataSource(), getQueryTimeout());  }}

DataSourceUtils工具類We128資訊網(wǎng)——每日最新資訊28at.com

public abstract class DataSourceUtils {  public static void applyTimeout(Statement stmt, @Nullable DataSource dataSource, int timeout) throws SQLException {    ConnectionHolder holder = null;    if (dataSource != null) {      holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);    }    // 如果當(dāng)前事務(wù)執(zhí)行配置了超時時間    if (holder != null && holder.hasTimeout()) {      // 剩余事務(wù)超時將覆蓋指定的值。      stmt.setQueryTimeout(holder.getTimeToLiveInSeconds());    }    else if (timeout >= 0) {      // No current transaction timeout -> apply specified value.      stmt.setQueryTimeout(timeout);    }  }  }

ResourceHolderSupport類We128資訊網(wǎng)——每日最新資訊28at.com

public abstract class ResourceHolderSupport implements ResourceHolder {   public int getTimeToLiveInSeconds() {    double diff = ((double) getTimeToLiveInMillis()) / 1000;    int secs = (int) Math.ceil(diff);    // 檢查超時時間    checkTransactionTimeout(secs <= 0);    return secs;  }  private void checkTransactionTimeout(boolean deadlineReached) throws TransactionTimedOutException {    if (deadlineReached) {      // 設(shè)置事務(wù)回滾      setRollbackOnly();      // 拋出異常      throw new TransactionTimedOutException("Transaction timed out: deadline was " + this.deadline);    }  }}

完畢!!!We128資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-13279-0.htmlSpring事務(wù)超時到底是怎么回事?

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 如何搭建高性能廣告技術(shù)需求方平臺

下一篇: 程序員必會之最詳細(xì)的ThreadPoolExecutor 線程池七大參數(shù)含義

標(biāo)簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 杨浦区| 屯留县| 阿勒泰市| 西藏| 长乐市| 咸宁市| 冷水江市| 镇康县| 苍南县| 布尔津县| 海晏县| 分宜县| 山阴县| 河曲县| 疏附县| 益阳市| 马公市| 宁德市| 牟定县| 高阳县| 鹤岗市| 铜陵市| 商城县| 茶陵县| 广元市| 陆河县| 漳平市| 富川| 虹口区| 香格里拉县| 江西省| 镇平县| 遂昌县| 齐河县| 福鼎市| 剑河县| 牡丹江市| 千阳县| 虞城县| 崇阳县| 江北区|