2012-09-26 36 views
7

我有一个关于@Transactional注释如何管理代码和事务执行的问题。给定一个正确安装Spring应用程序和下面的代码:使用@Transactional进行线程安全

@Transactional 
public void withdraw(int amount) { 
    if(isEnoughFunds(amount)) { 
     decreaseFunds(amount); 
    } 
} 

是否有可能出现以下情况:

  • 资金== 100;量== 100
  • 线程A进入退出/交易A开始
  • 线程A执行isEnoughFunds其评估为真
  • 线程B进入退出/交易B开始
  • 线程B执行isEnoughFunds其评估为真
  • 线程A执行decreaseFunds /线程A锁定了数据库记录
  • 线程B等待线程A提交事务,并释放写锁
  • 线程A退出抽取/事务A提交
  • 线程B执行decreaseFunds /线程B锁定数据库记录
  • 线程B出口抽取/事务B提交
  • 资金== -100

如果这是可能的,你将如何避免呢?

+2

注解只是说在交易中包装这个。数据库隔离级别决定了发生多少交织。 –

回答

3

是的,这可能取决于隔离级别。为了防止它,你可以在调用ifEnoughFunds()之前明确地从数据库获得一个读锁。锁定将在交易结束时释放。在这种情况下,线程B将始终等待线程的A事务在检查之前提交。

+4

你可以用一个代码示例进一步解释如何在春季和冬眠期间做到这一点?谢谢! –