【发布时间】:2017-07-10 23:10:39
【问题描述】:
首先看一下下面的代码,我有三个主要模型来管理StoreHouse和StoreHouseInvetory,还有一个名为StoreHouseInventoryLock的模型来临时锁定/解锁一些StoreHouseInvetory当其他进程想要使用这些模型时:
public class StoreHouse {
private String name;
private Double currentAmount;
}
public class StoreHouseInventory {
private StoreHouse storeHouse;
private Good good;
private Double amount;
}
public class StoreHouseInventoryLock {
private StoreHouseInventory inventory;
private Double amount;
}
@Service
public class PermitService implements IPermitService {
@Autowired
private IStoreHouseInventoryLockService storeHouseInventoryLockService;
@Autowired
private IStoreHouseService storeHouseService;
@Override
@Transactional
public void addDetailToPermitFromStoreHouseInventory(long permitId, long storeHouseId, long inventoryId, double amount) {
// do some business logic here
/* save is simple method
* and uses Session.save(object)
*/
storeHouseInventoryLockService.add(inventoryId, +amount);
// do some business logic here
storeHouseService.syncCurrentInventory(storeHouseId);
}
}
@Service
public class StoreHouseService implements IStoreHouseService {
@Autowired
private IStoreHouseInventoryService storeHouseInventoryService;
@Autowired
private IStoreHouseInventoryLockService storeHouseInventoryLockService;
@Transactional
public void syncCurrentInventory(storeHouseId) {
/* is a simeple method that use query like below
* select sum(e.amount)
* from StoreHouseInventory
* where e.storeHouse.id = :storeHouseId
*/
Double sumOfInventory = storeHouseInventoryService.sumOfInventory(storeHouseId);
/* is a simeple method that use query like below
* select sum(e.amount)
* from StoreHouseInventoryLock
* where e.storeHouseInventory.storeHouse.id = :storeHouseId
*/
Double sumOfLock = storeHouseInventoryService.sumOfLock(storeHouseId);
// load method is a simple method to load object by it's id
// and used from Session.get(String entityName, Serializable id)
StoreHouse storeHouse = this.load(storeHouseId);
storeHouse.setCurrentAmount(sumOfInventory - sumOfLock);
this.save(storeHouse);
}
}
问题是在StoreHouseService.syncCurrentInventory中调用storeHouseInventoryService.sumOfLock时,不知道storeHouseInventoryLockService.add方法在PermitService.addDetailToPermitFromStoreHouseInventory方法中的变化,导致锁总和计算错误。
我认为这是因为当我调用 storeHouseInventoryLockService.add 时会话未刷新。如果是真的,为什么休眠在此更改期间不刷新会话?如果没有,我该怎么办?
【问题讨论】:
-
对于初学者来说,你的代码有缺陷,你不应该捕获异常并吞下,你的代码会破坏正确的 tx 管理。数据在同一个事务中是可见的,并且当查询数据库时,hibernate 会自动刷新挂起的更改。如果那没有发生,那么您可能是在 hibernate 后面做的事情。添加同步方法(和相关对象)的代码。
-
对不起,是我的错,我删除了
try, catch块
标签: java spring hibernate spring-mvc hibernate-session