简体   繁体   English

并发更新Java中的Oracle表

[英]Concurrent updates to oracle table in Java


I'm developing an application with some kind of 'facebook like' feature. 我正在开发具有某种“类似于facebook”功能的应用程序。 Every time that a content published by a user is 'liked' he will have his punctuation increased. 每当用户“喜欢”发布的内容时,他的标点符号都会增加。 This app will be used by a large number of users around the company, so We are expecting a lot of concurrent updates to the same row. 该应用将被公司内的大量用户使用,因此我们期望同一行有很多并发更新。

simplified code 简化代码

User punctuation table 用户标点表

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


Java code 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();
                }
        }
}



We are afraid of deadlocks during updates. 我们担心更新期间会出现僵局。 Oracle allows to make the sum on a single query, I don't have to retrieve the value and make a second query to update with a new value, that's good. Oracle允许在单个查询中求和,我不必检索值并进行第二次查询以使用新值进行更新,这很好。 Also reading some other posts here, They said to create a synchronized block to lock an object, and let Java handle the synchronization between different threads. 他们还说在这里阅读其他文章,他们说创建一个同步块来锁定对象,并让Java处理不同线程之间的同步。 I choose the punctuation instance the method receives, this way I imagine that different combinations of user and value will allow concurrent acess to this methods, but will block an instance with same values (Do I have to implement equals() on Punctuation?) 我选择该方法接收的标点符号实例,这样我可以想象用户和值的不同组合将允许并发访问该方法,但是会阻塞具有相同值的实例(我是否必须在标点符号上实现equals()?)

Our database is Oracle 10g, Server Weblogic 11g, Java 6 and Linux (I dont know which flavor). 我们的数据库是Oracle 10g,Server Weblogic 11g,Java 6和Linux(我不知道哪种口味)。

Thank you in advance! 先感谢您!

You're wrong on your synchronization strategy. 您的同步策略不对。 synchronized uses the intrinsic lock of the object between parentheses. synchronized使用括号之间的对象的固有锁定。 If you have two Punctuation instances that you might consider equal because they refer to the same user_id , Java doesn't care: 2 objects, so 2 locks, so no mutual exclusion. 如果您有两个Punctuation实例,因为它们引用相同的user_id ,您可能会认为它们相等,因此Java不会在意:2个对象,所以2个锁,所以没有互斥。

I really don't see why the above, without the synchronized , could generate deadlocks: you're updating a single row in the table. 我真的不明白为什么上面,没有synchronized ,可能会产生死锁:你更新表中的一行。 You could have a deadlock if you had two concurrent transaction with one updating user1, then user2, and the other one updating user2, then user1. 如果您有两个并发事务,其中一个更新用户1,然后是user2,而另一个更新用户2,然后是user1,那么您可能会陷入死锁。 But even then, the database would detect the deadlock and throw an exception for one of the transactions. 但是即使那样,数据库仍会检测到死锁并为事务之一抛出异常。

you need to use optimistic lock pattern. 您需要使用乐观锁定模式。 take a look here for more details 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

And probably this http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/The_CMP_Engine-Optimistic_Locking.html which is more low level details 可能是http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/The_CMP_Engine-Optimistic_Locking.html ,这是更底层的详细信息

After identification of concurrent issue using optimistic lock, you may want to prefer re-trying - you have a full control what to do 使用乐观锁识别并发问题后,您可能希望重试-您完全可以控制要做什么

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM