Java 违反了ORA 000001唯一约束

Java 违反了ORA 000001唯一约束,java,oracle,insert,ora-00001,batch-updates,Java,Oracle,Insert,Ora 00001,Batch Updates,我有一个Insert语句到一个主键为dep_id和emp_id的表中。我的java程序为一个新记录生成一个新的emp_id并插入它。例如,如果我有dep_id=100和emp_id=25,我无法插入dep_id=100和emp_id=26的记录,但我可以插入dep_id=100和emp_id=27的记录。我通过select语句检查是否存在这种组合(dep_id=100和emp_id=26)。没有那种东西。我还是做了一件事 从dep_id=100和emp_id=26处删除并提交 只是为了确定,然后

我有一个Insert语句到一个主键为dep_id和emp_id的表中。我的java程序为一个新记录生成一个新的emp_id并插入它。例如,如果我有dep_id=100和emp_id=25,我无法插入dep_id=100和emp_id=26的记录,但我可以插入dep_id=100和emp_id=27的记录。我通过select语句检查是否存在这种组合(dep_id=100和emp_id=26)。没有那种东西。我还是做了一件事 从dep_id=100和emp_id=26处删除并提交 只是为了确定,然后尝试插入,但仍然不起作用。可能有什么问题?下面是代码:修改的DDL和Insert语句(从Eclipse控制台获得)

)


请注意,Insert语句本身有另一个Insert语句作为值。这个Insert语句(主语句)在应用程序的许多其他地方都有使用。此外,我使用100的dep_id是一个测试dep_id。除了我之外,没有人使用它。

创建Oracle序列:

CREATE SEQUENCE emp_id_seq MINVALUE 1 START WITH 1 INCREMENT BY 1; 
现在,您可以在代码中对该序列调用“nextval”方法(这可以通过JDBC或几乎所有ORM(如果不是全部的话)来完成),也可以在该列上放置一个触发器,该触发器会自动从序列中获取nextval,并在执行插入操作时将其插入表中(oracle上的IIRC在触发器中使用'BEFORE INSERT'运算符)

e、 g

这样做是线程安全的,您永远不会看到这样的冲突发生

如果您坚持在java代码中执行此操作(比如DBA不允许您创建另一个序列,但为什么不呢?如果他们不允许,我会感到惊讶),那么您必须使该方法线程安全。可能最好创建一个单例(您可以创建单例EJB)使用同步方法来提供下一个值。您从该单例类而不是任何其他类或ejb获取id,以避免出现像现在这样的问题(无论当前问题是否正是因为此,您现在遇到的是多线程环境中多个线程与非同步方法发生冲突的典型情况)


同时,如果你真的想了解正在发生的事情,请使用调试器并观察变量,以查看现有代码正在生成什么。调试器和手表是你的朋友。你最好的朋友。

你确定你的java代码是同步的吗?它可能会被多个线程调用。这是一个带有ut您描述的任何线程都没有意义。或者您遗漏了某些部分(例如,另一个可能运行不同应用程序的会话正在插入和提交一行
dep\u id=100
emp\u id=26
)或者您的描述不正确。您可以发布DDL来创建表,并发布一些我们可以在机器上运行的示例代码来复制问题吗?@Raghu-您知道
max(emp\u id)+1
在多用户环境中不起作用,对吗?同时运行的两个会话将看到相同的
max(emp\u id)
并将尝试插入具有相同
emp\u id
值的行,从而导致您描述的错误。您不使用序列生成密钥是有原因的吗?努乌,让我们开始切巴!尼尼娜aaggghhhh…多用户+选择最大值=您不想活下去。如果您想使用序列/自动增量,请与我一起使用live:)感谢BillR和今天帮助我的所有人。虽然我仍然不知道是什么导致了问题,但我也在考虑必须改变获得下一个值的方式。我将继续。
  CREATE UNIQUE INDEX "TestDB"."table1_PK" ON "TestDB"."table1" ("dep_id", "emp_id") 


     INSERT into table1            (dep_id,emp_id,status,new_sql_stmt,tab_name,col_name,query_type,NAME)values('100','26','Unlock','INSERT into testTab(id_some,nm_some,id_some_origin,flag,some_code,author,order) values  (''S11111111'',''trialSome00'','''',''y'','''',''100'',0)','testTab','nm_some','INSERT','trialSome00')
CREATE SEQUENCE emp_id_seq MINVALUE 1 START WITH 1 INCREMENT BY 1; 
create or replace trigger mytable_emp_id_trigger
before insert on mytable
for each row
begin
    select emp_id_seq.nextval into :emp.id from dual;
end;
/