Concurrently running spring framework transactions updating incorrect dataSpring @Transactional - isolation, propagationWhat exactly is Spring Framework for?Spring - @Transactional - What happens in background?Difference between applicationContext.xml and spring-servlet.xml in Spring FrameworkWhat is the difference between @Inject and @Autowired in Spring Framework? Which one to use under what condition?Spring @Transactional - isolation, propagationWhat is difference between CrudRepository and JpaRepository interfaces in Spring Data JPA?MyBatis Spring transaction on Mysql, not rolling backSpring Boot - websocket controller problemsUsing RowMapper and JdbcTemplate got NullPointerExceptionSpring Boot Transaction Rollback
What ability do tools use?
Generate Brainfuck for the numbers 1–255
Are differences between uniformly distributed numbers uniformly distributed?
Does the Fireball spell damage objects?
Why did I get only 5 points even though I won?
How does "Te vas a cansar" mean "You're going to get tired"?
A continuous water "planet" ring around a star
Why are Tucker and Malcolm not dead?
Not going forward with internship interview process
Can the ground attached to neutral fool a receptacle tester?
How to divide item stack in MC PE?
How do some PhD students get 10+ papers? Is that what I need for landing good faculty position?
Breadcrumb history decision
How can God warn people of the upcoming rapture without disrupting society?
Do I have to cite common CS algorithms?
Can sampling rate be a floating point number?
Super Duper Vdd stiffening required on 555 timer, what is the best way?
How would timezones work on a planet 100 times the size of our Earth
Is this n-speak?
How to assign many blockers at the same time?
If clocks themselves are based on light signals, wouldn't we expect the measured speed of light to always be the same constant?
TEMPO: play a (mp3) sound in animated GIF/PDF/SVG
Why is the result of ('b'+'a'+ + 'a' + 'a').toLowerCase() 'banana'?
What should I call bands of armed men in the Middle Ages?
Concurrently running spring framework transactions updating incorrect data
Spring @Transactional - isolation, propagationWhat exactly is Spring Framework for?Spring - @Transactional - What happens in background?Difference between applicationContext.xml and spring-servlet.xml in Spring FrameworkWhat is the difference between @Inject and @Autowired in Spring Framework? Which one to use under what condition?Spring @Transactional - isolation, propagationWhat is difference between CrudRepository and JpaRepository interfaces in Spring Data JPA?MyBatis Spring transaction on Mysql, not rolling backSpring Boot - websocket controller problemsUsing RowMapper and JdbcTemplate got NullPointerExceptionSpring Boot Transaction Rollback
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have created a simple spring boot application which will demonstrate how the bank transactions happens.I have created one 'Account' entity and created one 'debit' rest endpoint.
Here I am calling 'debit' api two times concurrently but only one time amount is debited.I want to know how can I lock the account entity so that another thread will read updated balance and will debit second time too.
I tried to lock 'account' entity with lock mode type as PESSIMISTIC_WRITE but its not working.
Account.java
package hello;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
@Table(name = "account")
@Entity // This tells Hibernate to make a table out of this class
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Account
//@Version
@Column(name="version")
private Integer version;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer userId;
@Column(name = "name")
private String name;
@Column(name="balance")
private int balance;
public Integer getUserId()
return userId;
public void setUserId(Integer userId)
this.userId = userId;
public int getBalance()
return balance;
public void setBalance(int balance)
this.balance = balance;
public String getName()
return name;
public void setName(String name)
this.name = name;
@Override
public String toString()
return "Account" +
"userId=" + userId +
", name='" + name + ''' +
", balance=" + balance +
'';
Rest end point is
@GetMapping(path = "/debit")
public ResponseEntity<String> debit()
Integer withdrawAmount = 100;
Integer userId = 1;
log.debug("debit from account id ",withdrawAmount,userId);
accountService.debit(userId,withdrawAmount);
return ResponseEntity.badRequest().body("debited");
AccountService.java
package hello.service;
import hello.Account;
import hello.AccountRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import java.util.Optional;
@Service
public class AccountService
final private Logger log = LoggerFactory.getLogger(AccountService.class);
@Autowired
private AccountRepository accountRepository;
@Autowired
private EntityManager entityManager;
@Transactional
public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
AccountRepository.java
package hello;
import org.springframework.data.repository.CrudRepository;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface AccountRepository extends CrudRepository<Account, Integer>
Account findOneByUserId(Integer userId);
my database record is -
click here to see the image
To test this scenario I have written on bash script
debit.sh
curl -I 'http://localhost:8080/demo/debit' &
curl -I 'http://localhost:8080/demo/debit' &
run this with bash debit.sh
So it can call same rest endpoint twice.
The output I am getting is
2019-03-27 14:17:36.375 DEBUG 11191 --- [nio-8080-exec-3] hello.MainController : debit 100 from account id 1
2019-03-27 14:17:36.376 DEBUG 11191 --- [nio-8080-exec-4] hello.MainController : debit 100 from account id 1
2019-03-27 14:17:36.394 DEBUG 11191 --- [nio-8080-exec-4] hello.service.AccountService : current balance 100
2019-03-27 14:17:36.394 DEBUG 11191 --- [nio-8080-exec-3] hello.service.AccountService : current balance 100
2019-03-27 14:17:36.395 DEBUG 11191 --- [nio-8080-exec-4] hello.service.AccountService : debited
2019-03-27 14:17:36.396 DEBUG 11191 --- [nio-8080-exec-3] hello.service.AccountService : debited
In both the transactions reading current balance as 100 and debiting same.
What I want here is It should update balance as -100.
java spring transactional
add a comment |
I have created a simple spring boot application which will demonstrate how the bank transactions happens.I have created one 'Account' entity and created one 'debit' rest endpoint.
Here I am calling 'debit' api two times concurrently but only one time amount is debited.I want to know how can I lock the account entity so that another thread will read updated balance and will debit second time too.
I tried to lock 'account' entity with lock mode type as PESSIMISTIC_WRITE but its not working.
Account.java
package hello;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
@Table(name = "account")
@Entity // This tells Hibernate to make a table out of this class
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Account
//@Version
@Column(name="version")
private Integer version;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer userId;
@Column(name = "name")
private String name;
@Column(name="balance")
private int balance;
public Integer getUserId()
return userId;
public void setUserId(Integer userId)
this.userId = userId;
public int getBalance()
return balance;
public void setBalance(int balance)
this.balance = balance;
public String getName()
return name;
public void setName(String name)
this.name = name;
@Override
public String toString()
return "Account" +
"userId=" + userId +
", name='" + name + ''' +
", balance=" + balance +
'';
Rest end point is
@GetMapping(path = "/debit")
public ResponseEntity<String> debit()
Integer withdrawAmount = 100;
Integer userId = 1;
log.debug("debit from account id ",withdrawAmount,userId);
accountService.debit(userId,withdrawAmount);
return ResponseEntity.badRequest().body("debited");
AccountService.java
package hello.service;
import hello.Account;
import hello.AccountRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import java.util.Optional;
@Service
public class AccountService
final private Logger log = LoggerFactory.getLogger(AccountService.class);
@Autowired
private AccountRepository accountRepository;
@Autowired
private EntityManager entityManager;
@Transactional
public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
AccountRepository.java
package hello;
import org.springframework.data.repository.CrudRepository;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface AccountRepository extends CrudRepository<Account, Integer>
Account findOneByUserId(Integer userId);
my database record is -
click here to see the image
To test this scenario I have written on bash script
debit.sh
curl -I 'http://localhost:8080/demo/debit' &
curl -I 'http://localhost:8080/demo/debit' &
run this with bash debit.sh
So it can call same rest endpoint twice.
The output I am getting is
2019-03-27 14:17:36.375 DEBUG 11191 --- [nio-8080-exec-3] hello.MainController : debit 100 from account id 1
2019-03-27 14:17:36.376 DEBUG 11191 --- [nio-8080-exec-4] hello.MainController : debit 100 from account id 1
2019-03-27 14:17:36.394 DEBUG 11191 --- [nio-8080-exec-4] hello.service.AccountService : current balance 100
2019-03-27 14:17:36.394 DEBUG 11191 --- [nio-8080-exec-3] hello.service.AccountService : current balance 100
2019-03-27 14:17:36.395 DEBUG 11191 --- [nio-8080-exec-4] hello.service.AccountService : debited
2019-03-27 14:17:36.396 DEBUG 11191 --- [nio-8080-exec-3] hello.service.AccountService : debited
In both the transactions reading current balance as 100 and debiting same.
What I want here is It should update balance as -100.
java spring transactional
add a comment |
I have created a simple spring boot application which will demonstrate how the bank transactions happens.I have created one 'Account' entity and created one 'debit' rest endpoint.
Here I am calling 'debit' api two times concurrently but only one time amount is debited.I want to know how can I lock the account entity so that another thread will read updated balance and will debit second time too.
I tried to lock 'account' entity with lock mode type as PESSIMISTIC_WRITE but its not working.
Account.java
package hello;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
@Table(name = "account")
@Entity // This tells Hibernate to make a table out of this class
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Account
//@Version
@Column(name="version")
private Integer version;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer userId;
@Column(name = "name")
private String name;
@Column(name="balance")
private int balance;
public Integer getUserId()
return userId;
public void setUserId(Integer userId)
this.userId = userId;
public int getBalance()
return balance;
public void setBalance(int balance)
this.balance = balance;
public String getName()
return name;
public void setName(String name)
this.name = name;
@Override
public String toString()
return "Account" +
"userId=" + userId +
", name='" + name + ''' +
", balance=" + balance +
'';
Rest end point is
@GetMapping(path = "/debit")
public ResponseEntity<String> debit()
Integer withdrawAmount = 100;
Integer userId = 1;
log.debug("debit from account id ",withdrawAmount,userId);
accountService.debit(userId,withdrawAmount);
return ResponseEntity.badRequest().body("debited");
AccountService.java
package hello.service;
import hello.Account;
import hello.AccountRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import java.util.Optional;
@Service
public class AccountService
final private Logger log = LoggerFactory.getLogger(AccountService.class);
@Autowired
private AccountRepository accountRepository;
@Autowired
private EntityManager entityManager;
@Transactional
public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
AccountRepository.java
package hello;
import org.springframework.data.repository.CrudRepository;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface AccountRepository extends CrudRepository<Account, Integer>
Account findOneByUserId(Integer userId);
my database record is -
click here to see the image
To test this scenario I have written on bash script
debit.sh
curl -I 'http://localhost:8080/demo/debit' &
curl -I 'http://localhost:8080/demo/debit' &
run this with bash debit.sh
So it can call same rest endpoint twice.
The output I am getting is
2019-03-27 14:17:36.375 DEBUG 11191 --- [nio-8080-exec-3] hello.MainController : debit 100 from account id 1
2019-03-27 14:17:36.376 DEBUG 11191 --- [nio-8080-exec-4] hello.MainController : debit 100 from account id 1
2019-03-27 14:17:36.394 DEBUG 11191 --- [nio-8080-exec-4] hello.service.AccountService : current balance 100
2019-03-27 14:17:36.394 DEBUG 11191 --- [nio-8080-exec-3] hello.service.AccountService : current balance 100
2019-03-27 14:17:36.395 DEBUG 11191 --- [nio-8080-exec-4] hello.service.AccountService : debited
2019-03-27 14:17:36.396 DEBUG 11191 --- [nio-8080-exec-3] hello.service.AccountService : debited
In both the transactions reading current balance as 100 and debiting same.
What I want here is It should update balance as -100.
java spring transactional
I have created a simple spring boot application which will demonstrate how the bank transactions happens.I have created one 'Account' entity and created one 'debit' rest endpoint.
Here I am calling 'debit' api two times concurrently but only one time amount is debited.I want to know how can I lock the account entity so that another thread will read updated balance and will debit second time too.
I tried to lock 'account' entity with lock mode type as PESSIMISTIC_WRITE but its not working.
Account.java
package hello;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
@Table(name = "account")
@Entity // This tells Hibernate to make a table out of this class
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Account
//@Version
@Column(name="version")
private Integer version;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer userId;
@Column(name = "name")
private String name;
@Column(name="balance")
private int balance;
public Integer getUserId()
return userId;
public void setUserId(Integer userId)
this.userId = userId;
public int getBalance()
return balance;
public void setBalance(int balance)
this.balance = balance;
public String getName()
return name;
public void setName(String name)
this.name = name;
@Override
public String toString()
return "Account" +
"userId=" + userId +
", name='" + name + ''' +
", balance=" + balance +
'';
Rest end point is
@GetMapping(path = "/debit")
public ResponseEntity<String> debit()
Integer withdrawAmount = 100;
Integer userId = 1;
log.debug("debit from account id ",withdrawAmount,userId);
accountService.debit(userId,withdrawAmount);
return ResponseEntity.badRequest().body("debited");
AccountService.java
package hello.service;
import hello.Account;
import hello.AccountRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import java.util.Optional;
@Service
public class AccountService
final private Logger log = LoggerFactory.getLogger(AccountService.class);
@Autowired
private AccountRepository accountRepository;
@Autowired
private EntityManager entityManager;
@Transactional
public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
AccountRepository.java
package hello;
import org.springframework.data.repository.CrudRepository;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface AccountRepository extends CrudRepository<Account, Integer>
Account findOneByUserId(Integer userId);
my database record is -
click here to see the image
To test this scenario I have written on bash script
debit.sh
curl -I 'http://localhost:8080/demo/debit' &
curl -I 'http://localhost:8080/demo/debit' &
run this with bash debit.sh
So it can call same rest endpoint twice.
The output I am getting is
2019-03-27 14:17:36.375 DEBUG 11191 --- [nio-8080-exec-3] hello.MainController : debit 100 from account id 1
2019-03-27 14:17:36.376 DEBUG 11191 --- [nio-8080-exec-4] hello.MainController : debit 100 from account id 1
2019-03-27 14:17:36.394 DEBUG 11191 --- [nio-8080-exec-4] hello.service.AccountService : current balance 100
2019-03-27 14:17:36.394 DEBUG 11191 --- [nio-8080-exec-3] hello.service.AccountService : current balance 100
2019-03-27 14:17:36.395 DEBUG 11191 --- [nio-8080-exec-4] hello.service.AccountService : debited
2019-03-27 14:17:36.396 DEBUG 11191 --- [nio-8080-exec-3] hello.service.AccountService : debited
In both the transactions reading current balance as 100 and debiting same.
What I want here is It should update balance as -100.
java spring transactional
java spring transactional
asked Mar 27 at 8:59
R KarwalkarR Karwalkar
61 bronze badge
61 bronze badge
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Please have a read, on the following answer: Spring @Transactional - isolation, propagation
In your case, I feel that setting the transaction as Read Commited
would do the trick, but if not, Serializable
should fix your problem completely, but this would come with a performance cost.
I tried by adding @Transactional(isolation = Isolation.SERIALIZABLE) on method but still same problem.
– R Karwalkar
Mar 27 at 10:51
Can you try updating yourCacheConcurrencyStrategy
toTRANSACTIONAL
too and let us know of the result? The value you are using does the exact opposite of what you need.
– Sofo Gial
Mar 27 at 11:03
No success with @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
– R Karwalkar
Mar 27 at 11:31
add a comment |
I solved by making debit method in service to 'synchronized'.But it will decrease the performance as one request will wait for another to complete.I think The proper solution for this is to use locking mechanism -java-concurrent-locks
@Transactional
synchronized public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
// entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55373226%2fconcurrently-running-spring-framework-transactions-updating-incorrect-data%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
Please have a read, on the following answer: Spring @Transactional - isolation, propagation
In your case, I feel that setting the transaction as Read Commited
would do the trick, but if not, Serializable
should fix your problem completely, but this would come with a performance cost.
I tried by adding @Transactional(isolation = Isolation.SERIALIZABLE) on method but still same problem.
– R Karwalkar
Mar 27 at 10:51
Can you try updating yourCacheConcurrencyStrategy
toTRANSACTIONAL
too and let us know of the result? The value you are using does the exact opposite of what you need.
– Sofo Gial
Mar 27 at 11:03
No success with @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
– R Karwalkar
Mar 27 at 11:31
add a comment |
Please have a read, on the following answer: Spring @Transactional - isolation, propagation
In your case, I feel that setting the transaction as Read Commited
would do the trick, but if not, Serializable
should fix your problem completely, but this would come with a performance cost.
I tried by adding @Transactional(isolation = Isolation.SERIALIZABLE) on method but still same problem.
– R Karwalkar
Mar 27 at 10:51
Can you try updating yourCacheConcurrencyStrategy
toTRANSACTIONAL
too and let us know of the result? The value you are using does the exact opposite of what you need.
– Sofo Gial
Mar 27 at 11:03
No success with @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
– R Karwalkar
Mar 27 at 11:31
add a comment |
Please have a read, on the following answer: Spring @Transactional - isolation, propagation
In your case, I feel that setting the transaction as Read Commited
would do the trick, but if not, Serializable
should fix your problem completely, but this would come with a performance cost.
Please have a read, on the following answer: Spring @Transactional - isolation, propagation
In your case, I feel that setting the transaction as Read Commited
would do the trick, but if not, Serializable
should fix your problem completely, but this would come with a performance cost.
answered Mar 27 at 9:40
Sofo GialSofo Gial
6251 gold badge8 silver badges19 bronze badges
6251 gold badge8 silver badges19 bronze badges
I tried by adding @Transactional(isolation = Isolation.SERIALIZABLE) on method but still same problem.
– R Karwalkar
Mar 27 at 10:51
Can you try updating yourCacheConcurrencyStrategy
toTRANSACTIONAL
too and let us know of the result? The value you are using does the exact opposite of what you need.
– Sofo Gial
Mar 27 at 11:03
No success with @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
– R Karwalkar
Mar 27 at 11:31
add a comment |
I tried by adding @Transactional(isolation = Isolation.SERIALIZABLE) on method but still same problem.
– R Karwalkar
Mar 27 at 10:51
Can you try updating yourCacheConcurrencyStrategy
toTRANSACTIONAL
too and let us know of the result? The value you are using does the exact opposite of what you need.
– Sofo Gial
Mar 27 at 11:03
No success with @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
– R Karwalkar
Mar 27 at 11:31
I tried by adding @Transactional(isolation = Isolation.SERIALIZABLE) on method but still same problem.
– R Karwalkar
Mar 27 at 10:51
I tried by adding @Transactional(isolation = Isolation.SERIALIZABLE) on method but still same problem.
– R Karwalkar
Mar 27 at 10:51
Can you try updating your
CacheConcurrencyStrategy
to TRANSACTIONAL
too and let us know of the result? The value you are using does the exact opposite of what you need.– Sofo Gial
Mar 27 at 11:03
Can you try updating your
CacheConcurrencyStrategy
to TRANSACTIONAL
too and let us know of the result? The value you are using does the exact opposite of what you need.– Sofo Gial
Mar 27 at 11:03
No success with @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
– R Karwalkar
Mar 27 at 11:31
No success with @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
– R Karwalkar
Mar 27 at 11:31
add a comment |
I solved by making debit method in service to 'synchronized'.But it will decrease the performance as one request will wait for another to complete.I think The proper solution for this is to use locking mechanism -java-concurrent-locks
@Transactional
synchronized public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
// entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
add a comment |
I solved by making debit method in service to 'synchronized'.But it will decrease the performance as one request will wait for another to complete.I think The proper solution for this is to use locking mechanism -java-concurrent-locks
@Transactional
synchronized public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
// entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
add a comment |
I solved by making debit method in service to 'synchronized'.But it will decrease the performance as one request will wait for another to complete.I think The proper solution for this is to use locking mechanism -java-concurrent-locks
@Transactional
synchronized public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
// entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
I solved by making debit method in service to 'synchronized'.But it will decrease the performance as one request will wait for another to complete.I think The proper solution for this is to use locking mechanism -java-concurrent-locks
@Transactional
synchronized public void debit(Integer id,int balance)
Optional<Account> accountOptional = accountRepository.findById(id);
Account account = accountOptional.get();
// entityManager.refresh(account, LockModeType.PESSIMISTIC_WRITE);
final int oldBalance = account.getBalance();
log.debug("current balance ",oldBalance);
account.setBalance(oldBalance-balance);
accountRepository.save(account);
log.debug("debited");
answered Mar 27 at 11:05
R KarwalkarR Karwalkar
61 bronze badge
61 bronze badge
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55373226%2fconcurrently-running-spring-framework-transactions-updating-incorrect-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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