Scope of @Transactional











up vote
0
down vote

favorite
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
























  • 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 at 8:37















up vote
0
down vote

favorite
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
























  • 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 at 8:37













up vote
0
down vote

favorite
1









up vote
0
down vote

favorite
1






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 at 16:29









Karol Dowbecki

13.5k72745




13.5k72745










asked Nov 19 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 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 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 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 at 8:37












2 Answers
2






active

oldest

votes

















up vote
0
down vote













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 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 at 16:30


















up vote
0
down vote













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 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 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',
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








up vote
0
down vote













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 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 at 16:30















up vote
0
down vote













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 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 at 16:30













up vote
0
down vote










up vote
0
down vote









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 at 16:15









Karol Dowbecki

13.5k72745




13.5k72745












  • 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 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 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 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 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 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 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 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 at 16:30












up vote
0
down vote













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 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 at 16:44

















up vote
0
down vote













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 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 at 16:44















up vote
0
down vote










up vote
0
down vote









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 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 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 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 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 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 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 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 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 at 16:44




















 

draft saved


draft discarded



















































 


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

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

Refactoring coordinates for Minecraft Pi buildings written in Python