如何正确同步事务?
How to properly synchronise a transaction?
在以下情况下什么是正确的同步?
public class Product {
private int amountAvailable;
private User seller;
public int subtractFromAmountAvailable(int amount) {
amountAvailable = amountAvailable - amount;
return amountAvailable;
}
}
public class User {
private int account;
public int depositToAccount(int amount) {
deposit = deposit + amount;
return deposit;
}
public int withdrawFromAccount(int amount) {
deposit = deposit - amount;
return deposit;
}
}
如果用户购买了产品,则必须将金额转入卖家帐户,并且必须更新产品的 amountAvailable 字段。同步此事务的正确方法是什么?
下面的方法行得通吗?
public class Transaction {
public void performTransaction(User buyer, Product product, int amount) {
int totalCost = product.getCost() * amount;
synchronized (this) {
product.subtractFromAmountAvailable(amount);
product.getSeller().depositToAccount(totalCost);
buyer.withdrawFromAccount(totalCost);
}
}
}
没有几个原因。
当您在实例方法上使用同步时,调用线程会在调用该方法的实例上获取锁。
仅当涉及的所有不同线程都使用同一个锁时,锁定才有意义。在您的示例中,不同的线程如何知道使用相同的事务对象?
有一个更大的问题。应用程序需要能够水平扩展,将涉及多个 jvms,并且无论如何都不会在 jvms 之间共享像这样的对象锁。
使用数据库行级锁定会更有意义。使用一个事务,Select 你想用锁改变的行。然后您可以更新它们,并且在交易完成之前没有其他进程可以干涉。这样所有的应用程序实例都有一个共享锁。
在以下情况下什么是正确的同步?
public class Product {
private int amountAvailable;
private User seller;
public int subtractFromAmountAvailable(int amount) {
amountAvailable = amountAvailable - amount;
return amountAvailable;
}
}
public class User {
private int account;
public int depositToAccount(int amount) {
deposit = deposit + amount;
return deposit;
}
public int withdrawFromAccount(int amount) {
deposit = deposit - amount;
return deposit;
}
}
如果用户购买了产品,则必须将金额转入卖家帐户,并且必须更新产品的 amountAvailable 字段。同步此事务的正确方法是什么?
下面的方法行得通吗?
public class Transaction {
public void performTransaction(User buyer, Product product, int amount) {
int totalCost = product.getCost() * amount;
synchronized (this) {
product.subtractFromAmountAvailable(amount);
product.getSeller().depositToAccount(totalCost);
buyer.withdrawFromAccount(totalCost);
}
}
}
没有几个原因。
当您在实例方法上使用同步时,调用线程会在调用该方法的实例上获取锁。
仅当涉及的所有不同线程都使用同一个锁时,锁定才有意义。在您的示例中,不同的线程如何知道使用相同的事务对象?
有一个更大的问题。应用程序需要能够水平扩展,将涉及多个 jvms,并且无论如何都不会在 jvms 之间共享像这样的对象锁。
使用数据库行级锁定会更有意义。使用一个事务,Select 你想用锁改变的行。然后您可以更新它们,并且在交易完成之前没有其他进程可以干涉。这样所有的应用程序实例都有一个共享锁。