Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.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 在事务开始时锁定表_Java_Database_Hibernate_Locking - Fatal编程技术网

Java 在事务开始时锁定表

Java 在事务开始时锁定表,java,database,hibernate,locking,Java,Database,Hibernate,Locking,由于遗留代码问题,在向数据库插入新行时,我需要手动计算唯一索引,不能使用自动增量 问题是多个客户端(不同的机器)的多个插入可能同时发生。因此,我需要在当前事务处于活动状态时锁定id最高的行,以防其他事务读取该行。或者,我可以锁定整张桌子,防止任何读取。在这种情况下,时间不是问题,因为写入/读取非常罕见(问题是,使用悲观读取时,您正在阻止ID最高的行上的其他更新。如果要阻止其他人的选择,则需要使用悲观写入 我知道这看起来很奇怪,因为你不打算更新那一行……但是如果你想在执行SELECT时使用其他块,

由于遗留代码问题,在向数据库插入新行时,我需要手动计算唯一索引,不能使用自动增量


问题是多个客户端(不同的机器)的多个插入可能同时发生。因此,我需要在当前事务处于活动状态时锁定id最高的行,以防其他事务读取该行。或者,我可以锁定整张桌子,防止任何读取。在这种情况下,时间不是问题,因为写入/读取非常罕见(问题是,使用悲观读取时,您正在阻止ID最高的行上的其他更新。如果要阻止其他人的选择,则需要使用悲观写入

我知道这看起来很奇怪,因为你不打算更新那一行……但是如果你想在执行SELECT时使用其他块,你应该碱化并说:“嗨,所有……我读了这一行并将更新它”……这样他们就不被允许读那一行,因为DB引擎认为你会在提交之前修改它


根据文档,SERIALIZABLE本身会将所有普通SELECT语句转换为SELECT…在共享模式下锁定,因此不会超过您已明确执行的操作。

您是否可以选择实现服务并通过该服务公开数据库?不,遗憾的是,不可以。整个体系结构一团糟(长达15年)而且所有客户端都直接连接到数据库。当我现在实现它时,我会选择连接到DB的中央服务器和瘦客户端,它们只从服务器请求和显示数据。但遗憾的是,客户端有超过200k的LOC,完全重写它不是一个选项(每次生成一个唯一标识符如何?由基于时间的部分加上随机部分组成。或加密安全的唯一标识符。没有事务隔离或乐观锁定问题,易于实现。还有一个想法——使用序列。
public void insert(T entity) {
    EntityManager em = factory.createEntityManager();
    try {
        EntityTransaction transaction = em.getTransaction();
        try {
            transaction.begin();

            int id = 0;
            TypedQuery<MasterDataComplete> query = em.createQuery(
                    "SELECT m FROM MasterDataComplete m ORDER BY m.id DESC", MasterDataComplete.class);
            query.setMaxResults(1);
            query.setLockMode(LockModeType.PESSIMISTIC_READ);
            List<MasterDataComplete> results = query.getResultList();
            if (!results.isEmpty()) {
                MasterDataComplete singleResult = results.get(0);

                id = singleResult.getId() + 1;
            }

            entity.setId(id);

            em.persist(entity);
            transaction.commit();
        } finally {
            if (transaction.isActive()) {
                transaction.rollback();
            }
        }
    } finally {
        em.close();
    }
}