【问题标题】:java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint while running Oracle functionsjava.sql.SQLIntegrityConstraintViolationException: ORA-00001: 运行 Oracle 函数时的唯一约束
【发布时间】:2013-12-20 14:36:49
【问题描述】:

我收到 java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint error while running oracle function using mybatis。我将 Spring 事务配置为在 Serializable 中运行,且 readOnly 为 false。下面是我的映射器类

public interface ILockMapper {

    @Transactional(isolation=Isolation.SERIALIZABLE, readOnly=false)
    String aquireLock(final SpInOutFields input);

    @Transactional(isolation=Isolation.SERIALIZABLE, readOnly=false)
    String releaseLock(final SpInOutFields input);

}

我的aquireLock 方法运行我的oracle 函数,oracle 函数有两个插入语句。在插入数据之前,我使用给定数据的 select count(*) 检查数据是否存在。如果存在,我不会插入数据示例 pl sql 语句在下面

SELECT COUNT(*) INTO rowcount FROM kp_lock WHERE device_id = deviceId; 


   if rowcount = 0 then
      INSERT INTO kp_lock(device_id,lock_flag,request_time) values ( deviceId, 'YES', CURRENT_TIMESTAMP);
  status := threadSysId;
   else
  status := '';
   end if;

当我从 oracle 运行该函数时,它工作正常。当我运行单线程时它工作正常,但当我运行多线程时失败。

我的 JUNIT 测试课在下面,

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={"classpath:config/spring-context.xml"})
    public class TestSerialization {

        @Autowired
        ApplicationContext context;

        @Test
        public void testSerialize() throws InterruptedException{

            MultiThread multithread = context.getBean(MultiThread.class);
            MultiThread multithread1 = context.getBean(MultiThread.class);

            Thread thread = new Thread(multithread);
            Thread thread1 = new Thread(multithread1);

            thread.start();

            if(multithread == multithread1){
                System.out.println("Both refer same instance");
            }

            thread1.start();

try {
                thread.join();
                thread1.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

请帮我配置事务以同步方式运行。不知道哪里出错了

【问题讨论】:

    标签: java plsql oracle11g mybatis spring-transactions


    【解决方案1】:

    问题在于导致竞争条件的函数的非原子性。在多线程环境中,在检查记录是否存在和插入发生之间可能会执行一些其他线程。

    您无法仅通过事务配置来解决此问题。你需要做的是insert conditionally

    您似乎正在尝试实现自定义锁。考虑使用User Defined Locks

    【讨论】:

    • 感谢@Roman Konoval 的投入。我的问题有点复杂我正在尝试实现 FIFO 和组(JMS 方式,我不想添加 JMS 组件,从而使我的系统变得复杂)。让我检查一下用户定义的锁
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 2014-11-06
    • 2014-04-08
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    相关资源
    最近更新 更多