簡體   English   中英

@Transactional的范圍

[英]Scope of @Transactional

例如,我有這樣的代碼

@Transactional(propogation=PROPOGATION.REQUIRED)
public class codeForTest {

  public void doSomethins(){
    User user = userRepository.finduserById(userId);
    updateUserDetails(user);
    updateFewOtherDetails(user);
  }

}

public class DifferentClass{

  @Transactional(propogation=PROPOGATION.REQUIRED)
  updateUserDetails() {
    //UPDATES user object
  }

}

在上述幾種情況下,我得到了以下幾個例子。 我在本地計算機上沒有收到錯誤。 我的問題是,如果updateUserDetails()將提交事務,並且在執行updateFewOtherDetails()時,由於提交了事務,是否會引發異常? 我懷疑這是否在造成問題,因為在哪里用@Transactional注釋(傳播= PROPOGATION.REQUIRED)

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:81)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.checkRowCounts(BatchingBatch.java:151)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:128)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:111)
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:163)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:226)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:482)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 130 common frames omitted
 Wrapped by: org.springframework.orm.ObjectOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:297)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:221)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy1125.createUserSession(Unknown Source)

您正在使用具有樂觀鎖定功能的JPA(休眠)。 實際的例外:

org.springframework.orm.ObjectOptimisticLockingFailureException:批處理更新從更新[0]返回了意外的行數; 實際行數:0; 預期:1; 嵌套的異常是org.hibernate.StaleStateException:批處理更新從更新[0]返回了意外的行數; 實際行數:0; 預期:1

意味着當您的事務正在運行時,另一個事務更新了相同的行,Hibernate檢測到它們的陳舊狀態並回滾當前事務以避免數據一致性問題。 樂觀地鎖定競爭的資源可能會發生這種情況,但這並不壞,因為由於回滾,數據庫中的數據仍然保持一致。

有幾種方法可以解決此問題:

  • 重試導致ObjectOptimisticLockingFailureException的邏輯,並希望不會競爭下一個事務。
  • 放寬交易邊界,以執行一些更小,更快的交易
  • 應用程序邏輯中的隊列更新

兩種方法都標記為@Transactional ,將在單個事務的邊界內執行。

如果.finduserById()使用一個對象, .finduserById() user對象加載到不同事務的邊界中或從緩存中.finduserById()

確保您也已標記@Transactional第二個.updateFewOtherDetails()方法。

REQUIRED傳播的情況下,直到調用者序列結束,事務才提交。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM