java.sql.SQLIntegrityConstraintViolationException:ORA-00001:运行Oracle函数时的唯一约束

时间:2013-12-04 07:43:40

标签: java plsql oracle11g mybatis spring-transactions

我在使用mybatis运行oracle函数时遇到java.sql.SQLIntegrityConstraintViolationException:ORA-00001:唯一约束错误。我将spring事务配置为在Serializable中运行,并且readOnly为false。下面是我的mapper类

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函数有两个insert语句。在插入数据之前,我使用给定数据的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();
            }
        }

    }

有些人可以帮我配置以同步方式运行的事务。不知道我哪里出错了

1 个答案:

答案 0 :(得分:2)

问题在于导致竞争条件的功能的非原子性。在多线程环境中,如果记录存在且插入发生,则可以在检查之间执行某些其他线程。

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

看起来您正在尝试实现自定义锁。考虑使用User Defined Locks