Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用hibernate 4实现自定义线程安全序列?_Java_Multithreading_Hibernate_Spring Transactions_Transaction Isolation - Fatal编程技术网

Java 如何使用hibernate 4实现自定义线程安全序列?

Java 如何使用hibernate 4实现自定义线程安全序列?,java,multithreading,hibernate,spring-transactions,transaction-isolation,Java,Multithreading,Hibernate,Spring Transactions,Transaction Isolation,我需要实现一个解决方案,为不同类型但类型相同(同一类,同一表)的对象生成序列号。此外,序列生成的规则在运行时定义(开始序列、最大数量等)。 我使用的是MySQL,hibernate MySQL5方言不支持序列生成,因此我选择使用序列表实现此功能,其中每一行都是不同类型对象的序列: +--------------------+--------------+------+-----+---------+-------+ | Field | Type | Nu

我需要实现一个解决方案,为不同类型但类型相同(同一类,同一表)的对象生成序列号。此外,序列生成的规则在运行时定义(开始序列、最大数量等)。 我使用的是MySQL,hibernate MySQL5方言不支持序列生成,因此我选择使用序列表实现此功能,其中每一行都是不同类型对象的序列:

+--------------------+--------------+------+-----+---------+-------+
| Field              | Type         | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+-------+
| seqenceName        | varchar(255) | NO   | PRI | NULL    |       | 
| nextVal            | bigint(20)   | NO   |     | NULL    |       | 
+--------------------+--------------+------+-----+---------+-------+
我创建了一个增加值的dao:

public synchronized long getNextValue(String seqenceName) throws MySequenceNotFoundException {

        MySequence seq = findByID(seqenceName);

        if (seq == null) {
            throw new MySequenceNotFoundException("Sequence does not exist with name: " + seqenceName);
        }//if not exists

        long nextVal = seq.getNextVal();
        getCurrentSession().saveOrUpdate(seq);

        return nextVal;
    }
这从服务层调用为:

@Transactional(readOnly=false, propagation=Propagation.REQUIRES_NEW, isolation=Isolation.SERIALIZABLE)
    public synchronized long incSequence(String seqName) throws MySequenceNotFoundException {

        getCurrentSession().getTransaction().begin();

        MySequence seq = sequenceDao.findByID(seqName);

        LockRequest lockRequest = getCurrentSession().buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE));
        lockRequest.lock(seq);

        long l = sequenceDao.getNextValue(seqName);
        getCurrentSession().getTransaction().commit();

        return l;
    }
我尝试了一切:将隔离级别设置为
isolation.SERIALIZABLE
,以编程方式在方法内提交事务,向其中添加
synchronized
关键字,还添加了锁请求,但我认为它已经过时,因为隔离级别已经设置好了

尽管如此,如果我创建100个线程并从每个线程调用此方法60次,结果是
nextVal
列的值约为4000,而不是6000

我怀疑我在这里遗漏了一些非常基本的东西,但我无法找到这项工作所需要的东西


谢谢你的提示

它看起来像原子变量问题:)请看一看并尝试使用AtomicIntegrater而不是int。

答案似乎在于一个相关的问题:


<>我唯一错过的是每次调用递增计数器时调用<代码> GeCurrutsSession().FrHuSH()/代码>,因为我没有考虑到我的服务层为测试客户机创建的每个线程使用一个单独的会话,因此,如果不刷新会话,我无法同步线程之间的计数器。

使用
选择。。。有关更新
,Hibernate支持它-请参阅我的

谢谢你的回答,但这与我的问题无关。。。从性能的角度来看,同步方法可能不是最优的,但它们应该具有相同的效果。更重要的是,我认为理想情况下我不需要同步,因为它应该在DB事务级别上得到保证。。。同步方法只是出于恐慌而完成的:)谢谢你的回答!是的,这也是一个可行的选择。我也会用这个做个测试。嗨,你找到解决问题的方法了吗?我也面临同样的问题。