我的问题是,首先,hibernate spring事务是否同步?
如果不是,如果我同时使用同一个对象开始两个事务,会发生什么?
我很乐意向您展示这个示例:
我有一个 Player
对象和一个 Ship
对象
玩家
- 黄金
- 设置船只
发货
- 实际价格
我有一个这样的方法:
session.beingTrasaction()
// if player have enough gold, start one query to set gold to gold-price, and second query to add new ship
session.getTransaction().commit();
这可以安全使用吗?如果我使用同一个玩家多次调用这样的算法,它们会串行执行吗?
非常欢迎任何帮助或解释
解决方案:
感谢我在这里得到的帮助,我通过使用 hibernate locking 找到了我的解决方案,我选择使用悲观锁,其实也挺简单的。
就我而言,这是我的实现:
我添加到播放器
:
private Long databaseVersion;
@Version
public Long getDatabaseVersion() {
return databaseVersion;
}
public void setDatabaseVersion(Long databaseVersion) {
this.databaseVersion = databaseVersion;
}
还有我的 dao 工具:
public void buyShip(Player player, Ship ship) {
Session session = sessionFactory.openSession();
session.beginTransaction();
Player p = (Player) session.get(Player.class, player.getId(), LockMode.PESSIMISTIC_WRITE);
if(p.getGold()>=ship.getPrice()) {
ship.setPlayer(player);
addShipToUser(session,ship);
p.setGold(player.getGold()-ship.getPrice());
session.update(p);
}else {
System.out.println("NOT EN GOLD");
}
session.getTransaction().commit();
session.close();
}
我用 5 个线程检查它,它工作了!我对同一播放器的所有更改都将串行执行,而对不同播放器的更改将并行执行!
最佳答案
不存在 Spring 事务这样的东西。 Spring仅为事务管理提供一致的抽象来启动和提交/回滚事务。
public interface PlatformTransactionManager {
TransactionStatus getTransaction(
TransactionDefinition definition) throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
但是您必须将管理实际事务的实际实现注入(inject)其中。例如,hibernate 事务的抽象是 HibernateTransactionManager,并且您必须注入(inject) Hibernate 的 SessionFactory,后者执行实际的开始/提交/回滚操作。
除此之外,如果两个线程执行同一个事务:
session.beingTrasaction()
if (player.gold > 10){
player.setGold(gold - 10);
Ship newShip = new Ship();
player.addShip(newShip); // I suppose you have cascade insert otherwise you have to save your transient ship
}
session.getTransaction().commit();
事务将以串行方式提交。但是,您最终可能会遇到金币数量为负的玩家。
Thread 1 Thread 2
if (player.gold > 10) // true
if (player.gold > 10) // true
player.gold = gold - 10 // gold=0
player.gold = gold - 10 // gold=-10
您需要optimistic或pessimistic锁定。
关于java - Q : hibernate spring transaction is synchronized ? 如果没有,我如何更新数据库安全线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42585379/