Scope of @Transactional












0














For example, I have a code something like this



@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
}

}


I am getting the following in couple of instances with the above logic. I don't get an error in local machine. My question is if updateUserDetails() will commit the transaction and when updateFewOtherDetails() is executed, since the transaction is committed, is it throwing the exception ? I doubt if that is creating the problem since where are annotating it with @Transactional (propogation= 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)









share|improve this question
























  • In the comments below you note that By the way, updateUserDetails() is in codeForTest class but it a private method. which is completely different from the code you have posted. Maybe if you asked a coherent question you might get an answer.
    – Alan Hay
    Nov 20 '18 at 8:37
















0














For example, I have a code something like this



@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
}

}


I am getting the following in couple of instances with the above logic. I don't get an error in local machine. My question is if updateUserDetails() will commit the transaction and when updateFewOtherDetails() is executed, since the transaction is committed, is it throwing the exception ? I doubt if that is creating the problem since where are annotating it with @Transactional (propogation= 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)









share|improve this question
























  • In the comments below you note that By the way, updateUserDetails() is in codeForTest class but it a private method. which is completely different from the code you have posted. Maybe if you asked a coherent question you might get an answer.
    – Alan Hay
    Nov 20 '18 at 8:37














0












0








0


1





For example, I have a code something like this



@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
}

}


I am getting the following in couple of instances with the above logic. I don't get an error in local machine. My question is if updateUserDetails() will commit the transaction and when updateFewOtherDetails() is executed, since the transaction is committed, is it throwing the exception ? I doubt if that is creating the problem since where are annotating it with @Transactional (propogation= 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)









share|improve this question















For example, I have a code something like this



@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
}

}


I am getting the following in couple of instances with the above logic. I don't get an error in local machine. My question is if updateUserDetails() will commit the transaction and when updateFewOtherDetails() is executed, since the transaction is committed, is it throwing the exception ? I doubt if that is creating the problem since where are annotating it with @Transactional (propogation= 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)






java spring hibernate jpa






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 16:29









Karol Dowbecki

17k82850




17k82850










asked Nov 19 '18 at 16:09









srinivas vishnu

142




142












  • In the comments below you note that By the way, updateUserDetails() is in codeForTest class but it a private method. which is completely different from the code you have posted. Maybe if you asked a coherent question you might get an answer.
    – Alan Hay
    Nov 20 '18 at 8:37


















  • In the comments below you note that By the way, updateUserDetails() is in codeForTest class but it a private method. which is completely different from the code you have posted. Maybe if you asked a coherent question you might get an answer.
    – Alan Hay
    Nov 20 '18 at 8:37
















In the comments below you note that By the way, updateUserDetails() is in codeForTest class but it a private method. which is completely different from the code you have posted. Maybe if you asked a coherent question you might get an answer.
– Alan Hay
Nov 20 '18 at 8:37




In the comments below you note that By the way, updateUserDetails() is in codeForTest class but it a private method. which is completely different from the code you have posted. Maybe if you asked a coherent question you might get an answer.
– Alan Hay
Nov 20 '18 at 8:37












2 Answers
2






active

oldest

votes


















0














You are using JPA (Hibernate) with optimistic locking. The actual exception:




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




means that while your transaction was running another transaction updated the same rows, Hibernate detected their stale state and rolled back current transaction to avoid data consistency problems. This can happen with optimistic locking on a contended resource, but it's not bad because due to rollback the data is still consistent in the database.



There are few ways you can resolve this:




  • Retry the logic that caused ObjectOptimisticLockingFailureException and hope that next transaction won't be contended.

  • Relax transaction boundaries to perform a few smaller and faster transaction

  • Queue updates in application logic






share|improve this answer





















  • I am very sure that no other thread is doing that. I doubt if updateUserDetails is that other transaction since it has got its own @Transactional and I am sending the that same User object to both the methods. Also, it is a highly consistent error.
    – srinivas vishnu
    Nov 19 '18 at 16:22










  • @srinivasvishnu currently your code doesn't even compile. Perhaps if you could provide more complete example one could analyze it better.
    – Karol Dowbecki
    Nov 19 '18 at 16:30



















0














Both the methods will be executed in bounds of single transaction, once they both marked @Transactional.



user object was loaded in bounds of different transaction or taken from cache, in a case .finduserById() uses the one.



Make sure you've marked @Transactional second .updateFewOtherDetails() method too.



With propagation REQUIRED the transaction won't commit until the end of caller sequence.






share|improve this answer





















  • Do you mean updateUserDetails() ? I already have an @Transactional on updateFewOtherDetails(). By the way, updateUserDetails() is in codeForTest class but it a private method. Will that make a difference ?
    – srinivas vishnu
    Nov 19 '18 at 16:37












  • @srinivasvishnu, yes, it will. Since Spring transactions are AOP based, the components are runtime proxies. It means, your methods have to be public and located in different Spring beans in relation to caller. Cross-member calls are not allowed with default configuration.
    – WildDev
    Nov 19 '18 at 16:44













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378609%2fscope-of-transactional%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














You are using JPA (Hibernate) with optimistic locking. The actual exception:




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




means that while your transaction was running another transaction updated the same rows, Hibernate detected their stale state and rolled back current transaction to avoid data consistency problems. This can happen with optimistic locking on a contended resource, but it's not bad because due to rollback the data is still consistent in the database.



There are few ways you can resolve this:




  • Retry the logic that caused ObjectOptimisticLockingFailureException and hope that next transaction won't be contended.

  • Relax transaction boundaries to perform a few smaller and faster transaction

  • Queue updates in application logic






share|improve this answer





















  • I am very sure that no other thread is doing that. I doubt if updateUserDetails is that other transaction since it has got its own @Transactional and I am sending the that same User object to both the methods. Also, it is a highly consistent error.
    – srinivas vishnu
    Nov 19 '18 at 16:22










  • @srinivasvishnu currently your code doesn't even compile. Perhaps if you could provide more complete example one could analyze it better.
    – Karol Dowbecki
    Nov 19 '18 at 16:30
















0














You are using JPA (Hibernate) with optimistic locking. The actual exception:




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




means that while your transaction was running another transaction updated the same rows, Hibernate detected their stale state and rolled back current transaction to avoid data consistency problems. This can happen with optimistic locking on a contended resource, but it's not bad because due to rollback the data is still consistent in the database.



There are few ways you can resolve this:




  • Retry the logic that caused ObjectOptimisticLockingFailureException and hope that next transaction won't be contended.

  • Relax transaction boundaries to perform a few smaller and faster transaction

  • Queue updates in application logic






share|improve this answer





















  • I am very sure that no other thread is doing that. I doubt if updateUserDetails is that other transaction since it has got its own @Transactional and I am sending the that same User object to both the methods. Also, it is a highly consistent error.
    – srinivas vishnu
    Nov 19 '18 at 16:22










  • @srinivasvishnu currently your code doesn't even compile. Perhaps if you could provide more complete example one could analyze it better.
    – Karol Dowbecki
    Nov 19 '18 at 16:30














0












0








0






You are using JPA (Hibernate) with optimistic locking. The actual exception:




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




means that while your transaction was running another transaction updated the same rows, Hibernate detected their stale state and rolled back current transaction to avoid data consistency problems. This can happen with optimistic locking on a contended resource, but it's not bad because due to rollback the data is still consistent in the database.



There are few ways you can resolve this:




  • Retry the logic that caused ObjectOptimisticLockingFailureException and hope that next transaction won't be contended.

  • Relax transaction boundaries to perform a few smaller and faster transaction

  • Queue updates in application logic






share|improve this answer












You are using JPA (Hibernate) with optimistic locking. The actual exception:




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




means that while your transaction was running another transaction updated the same rows, Hibernate detected their stale state and rolled back current transaction to avoid data consistency problems. This can happen with optimistic locking on a contended resource, but it's not bad because due to rollback the data is still consistent in the database.



There are few ways you can resolve this:




  • Retry the logic that caused ObjectOptimisticLockingFailureException and hope that next transaction won't be contended.

  • Relax transaction boundaries to perform a few smaller and faster transaction

  • Queue updates in application logic







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 19 '18 at 16:15









Karol Dowbecki

17k82850




17k82850












  • I am very sure that no other thread is doing that. I doubt if updateUserDetails is that other transaction since it has got its own @Transactional and I am sending the that same User object to both the methods. Also, it is a highly consistent error.
    – srinivas vishnu
    Nov 19 '18 at 16:22










  • @srinivasvishnu currently your code doesn't even compile. Perhaps if you could provide more complete example one could analyze it better.
    – Karol Dowbecki
    Nov 19 '18 at 16:30


















  • I am very sure that no other thread is doing that. I doubt if updateUserDetails is that other transaction since it has got its own @Transactional and I am sending the that same User object to both the methods. Also, it is a highly consistent error.
    – srinivas vishnu
    Nov 19 '18 at 16:22










  • @srinivasvishnu currently your code doesn't even compile. Perhaps if you could provide more complete example one could analyze it better.
    – Karol Dowbecki
    Nov 19 '18 at 16:30
















I am very sure that no other thread is doing that. I doubt if updateUserDetails is that other transaction since it has got its own @Transactional and I am sending the that same User object to both the methods. Also, it is a highly consistent error.
– srinivas vishnu
Nov 19 '18 at 16:22




I am very sure that no other thread is doing that. I doubt if updateUserDetails is that other transaction since it has got its own @Transactional and I am sending the that same User object to both the methods. Also, it is a highly consistent error.
– srinivas vishnu
Nov 19 '18 at 16:22












@srinivasvishnu currently your code doesn't even compile. Perhaps if you could provide more complete example one could analyze it better.
– Karol Dowbecki
Nov 19 '18 at 16:30




@srinivasvishnu currently your code doesn't even compile. Perhaps if you could provide more complete example one could analyze it better.
– Karol Dowbecki
Nov 19 '18 at 16:30













0














Both the methods will be executed in bounds of single transaction, once they both marked @Transactional.



user object was loaded in bounds of different transaction or taken from cache, in a case .finduserById() uses the one.



Make sure you've marked @Transactional second .updateFewOtherDetails() method too.



With propagation REQUIRED the transaction won't commit until the end of caller sequence.






share|improve this answer





















  • Do you mean updateUserDetails() ? I already have an @Transactional on updateFewOtherDetails(). By the way, updateUserDetails() is in codeForTest class but it a private method. Will that make a difference ?
    – srinivas vishnu
    Nov 19 '18 at 16:37












  • @srinivasvishnu, yes, it will. Since Spring transactions are AOP based, the components are runtime proxies. It means, your methods have to be public and located in different Spring beans in relation to caller. Cross-member calls are not allowed with default configuration.
    – WildDev
    Nov 19 '18 at 16:44


















0














Both the methods will be executed in bounds of single transaction, once they both marked @Transactional.



user object was loaded in bounds of different transaction or taken from cache, in a case .finduserById() uses the one.



Make sure you've marked @Transactional second .updateFewOtherDetails() method too.



With propagation REQUIRED the transaction won't commit until the end of caller sequence.






share|improve this answer





















  • Do you mean updateUserDetails() ? I already have an @Transactional on updateFewOtherDetails(). By the way, updateUserDetails() is in codeForTest class but it a private method. Will that make a difference ?
    – srinivas vishnu
    Nov 19 '18 at 16:37












  • @srinivasvishnu, yes, it will. Since Spring transactions are AOP based, the components are runtime proxies. It means, your methods have to be public and located in different Spring beans in relation to caller. Cross-member calls are not allowed with default configuration.
    – WildDev
    Nov 19 '18 at 16:44
















0












0








0






Both the methods will be executed in bounds of single transaction, once they both marked @Transactional.



user object was loaded in bounds of different transaction or taken from cache, in a case .finduserById() uses the one.



Make sure you've marked @Transactional second .updateFewOtherDetails() method too.



With propagation REQUIRED the transaction won't commit until the end of caller sequence.






share|improve this answer












Both the methods will be executed in bounds of single transaction, once they both marked @Transactional.



user object was loaded in bounds of different transaction or taken from cache, in a case .finduserById() uses the one.



Make sure you've marked @Transactional second .updateFewOtherDetails() method too.



With propagation REQUIRED the transaction won't commit until the end of caller sequence.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 19 '18 at 16:27









WildDev

1,07731949




1,07731949












  • Do you mean updateUserDetails() ? I already have an @Transactional on updateFewOtherDetails(). By the way, updateUserDetails() is in codeForTest class but it a private method. Will that make a difference ?
    – srinivas vishnu
    Nov 19 '18 at 16:37












  • @srinivasvishnu, yes, it will. Since Spring transactions are AOP based, the components are runtime proxies. It means, your methods have to be public and located in different Spring beans in relation to caller. Cross-member calls are not allowed with default configuration.
    – WildDev
    Nov 19 '18 at 16:44




















  • Do you mean updateUserDetails() ? I already have an @Transactional on updateFewOtherDetails(). By the way, updateUserDetails() is in codeForTest class but it a private method. Will that make a difference ?
    – srinivas vishnu
    Nov 19 '18 at 16:37












  • @srinivasvishnu, yes, it will. Since Spring transactions are AOP based, the components are runtime proxies. It means, your methods have to be public and located in different Spring beans in relation to caller. Cross-member calls are not allowed with default configuration.
    – WildDev
    Nov 19 '18 at 16:44


















Do you mean updateUserDetails() ? I already have an @Transactional on updateFewOtherDetails(). By the way, updateUserDetails() is in codeForTest class but it a private method. Will that make a difference ?
– srinivas vishnu
Nov 19 '18 at 16:37






Do you mean updateUserDetails() ? I already have an @Transactional on updateFewOtherDetails(). By the way, updateUserDetails() is in codeForTest class but it a private method. Will that make a difference ?
– srinivas vishnu
Nov 19 '18 at 16:37














@srinivasvishnu, yes, it will. Since Spring transactions are AOP based, the components are runtime proxies. It means, your methods have to be public and located in different Spring beans in relation to caller. Cross-member calls are not allowed with default configuration.
– WildDev
Nov 19 '18 at 16:44






@srinivasvishnu, yes, it will. Since Spring transactions are AOP based, the components are runtime proxies. It means, your methods have to be public and located in different Spring beans in relation to caller. Cross-member calls are not allowed with default configuration.
– WildDev
Nov 19 '18 at 16:44




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378609%2fscope-of-transactional%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

Npm cannot find a required file even through it is in the searched directory