1


我正在开发一个具有某种“facebook like”功能的应用程序。每次用户发布的内容被“喜欢”时,他的标点符号就会增加。该应用程序将被公司内的大量用户使用,因此我们预计同一行会有很多并发更新。

简化代码

用户标点表

Punctuation(
    userId NVARCHAR2(32),
    value NUMBER(10,0)
)/


Java 代码

public class Punctuation(){
    private String userId;
    private int value;

    public Punctuation(final String userId, final int value){
            this.userId = userId;
            this.value = value;
    }

    public String getUserId();
    public int getValue();

}

//simplified code
public final class PunctuationController{

    private PunctuationController(){}

    public static void addPunctuation(final Punctuation punctuation){

        final Transaction transaction = TransactionFactory.createTransaction();
        Connection conn = null;
        PreparedStatment statment = null;
        try{
                synchronized(punctuation){
                    transaction.begin();
                    conn = transaction.getConnection();
                    statment = conn.preparedStatment("UPDATE Punctuation SET value = value + ? where userId = ?");
                    statment.setString('1', punctuation.getUserId());
                    statment.setInt('2', punctuation.getValue());
                    transaction.commit();
                }
        }catch (Exception e){
                transaction.rollback();
        }finally{
                transaction.dispose();
                if(statment !=null){
                        statment.close();
                }
        }
}



我们害怕更新期间出现死锁。Oracle 允许对单个查询求和,我不必检索该值并进行第二次查询以使用新值进行更新,这很好。还在这里阅读了其他一些帖子,他们说创建一个同步块来锁定一个对象,并让Java处理不同线程之间的同步。我选择方法接收的标点符号实例,这样我想用户和值的不同组合将允许并发访问此方法,但会阻止具有相同值的实例(我必须在标点符号上实现 equals() 吗?

)数据库是 Oracle 10g、Server Weblogic 11g、Java 6 和 Linux(我不知道是哪种风格)。

先感谢您!

4

2 回答 2

3

你的同步策略错了。synchronized在括号之间使用对象的内在锁定。如果您有两个Punctuation实例,您可能认为它们相等,因为它们引用相同user_id,Java 不在乎:2 个对象,所以 2 个锁,所以没有互斥。

我真的不明白为什么上面没有synchronized, 会产生死锁:你正在更新表中的一行。如果您有两个并发事务,其中一个更新 user1,然后是 user2,另一个更新 user2,然后是 user1,您可能会遇到死锁。但即便如此,数据库也会检测到死锁并为其中一个事务抛出异常。

于 2012-07-31T10:44:53.817 回答
0

你需要使用乐观锁模式。在这里查看更多详细信息http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/The_CMP_Engine-Optimistic_Locking.html

可能这个http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/The_CMP_Engine-Optimistic_Locking.html这是更底层的细节

在使用乐观锁识别并发问题后,您可能希望重试 - 您可以完全控制要做什么

于 2012-07-31T10:45:14.923 回答