有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java中oracle表的多线程并发更新


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

简化代码

用户标点表

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、服务器Weblogic 11g、Java 6和Linux(我不知道是哪种风格)。

提前谢谢


共 (2) 个答案

  1. # 1 楼答案

    你的同步策略错了synchronized在括号之间使用对象的固有锁。如果你有两个{{CD2}}实例,你可能会认为它们是相等的,因为它们引用了相同的^ {CD3}},java不关心:2个对象,所以2个锁,所以不互斥。p>

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