我在Oracle 11g中创建了一个分区表,并尝试使用Java批处理作业中的多线程插入记录。 让我们说,如果我有10个线程,&每个人都希望同时插入/更新100万条记录或者在没有线程的情况下批量插入一些时间,在这两种情况下我们的表都被oracle锁定了同一个会话。如果我们有10个线程,那么我们为同一个表创建了10个会话的20条记录。这仅适用于具有子分区表的分区或分区。
下面是创建表格查询
CREATE TABLE "SEG_TEST_SINGLE_PARTITION"
(
"POR_CD" CHAR(2 CHAR) NOT NULL ENABLE,
"PROD_MNTH" CHAR(6 CHAR) NOT NULL ENABLE,
"INS_DTTM" TIMESTAMP (6)
)
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE
(
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT
)
TABLESPACE "a" PARTITION BY LIST
(
"POR_CD"
)
(
PARTITION "PWKLY_ORDR_POR01" VALUES
(
'01'
)
SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE(INITIAL 8388608 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "a" ,
PARTITION "PWKLY_ORDR_POR02" VALUES
(
'02'
)
SEGMENT CREATION DEFERRED PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "a" ,
PARTITION "PWKLY_ORDR_POR03" VALUES
(
'03'
)
SEGMENT CREATION DEFERRED PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "a" ,
PARTITION "PWKLY_ORDR_POR06" VALUES
(
'06'
)
SEGMENT CREATION DEFERRED PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "a" ,
PARTITION "PWKLY_ORDR_POR15" VALUES
(
'15'
)
SEGMENT CREATION DEFERRED PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "a" ,
PARTITION "PWKLY_ORDR_POR20" VALUES
(
'20'
)
SEGMENT CREATION DEFERRED PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "a" ,
PARTITION "PWKLY_ORDR_PORDF" VALUES
(
DEFAULT
)
SEGMENT CREATION DEFERRED PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE( BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "a"
);
通过以下查询,我检查了表锁
select a.INST_ID,a.XIDUSN,a.XIDSLOT,a.XIDSQN,a.OBJECT_ID,b.OBJECT_NAME,a.SESSION_ID,a.ORACLE_USERNAME,a.OS_USER_NAME,a.PROCESS,LOCKED_MODE from
GV$LOCKED_OBJECT a,dba_objects b where a.object_id=b.object_id and ORACLE_USERNAME like '%ASP01%' order by 8;
"INST_ID" "XIDUSN" "XIDSLOT" "XIDSQN" "OBJECT_ID" "OBJECT_NAME" "SESSION_ID" "ORACLE_USERNAME" "OS_USER_NAME" "PROCESS" "LOCKED_MODE"
3 58 16 424487 3235818 "PLAN_TABLE$" 2447 "ASP1" "z013" "15140" 3
所以到目前为止我没有锁定上面创建的表,现在我将运行Insert query而不提交,并将从sql developer(或从任何地方)检查锁定agian
Insert into SEG_TEST_SINGLE_PARTITION (POR_CD,PROD_MNTH,INS_DTTM) values ('02','201607',to_timestamp('15-DEC-16 11.15.09.000000000 PM','DD-MON-RR HH.MI.SS.FF AM'));
1 row inserted
锁定查询
select a.INST_ID,a.XIDUSN,a.XIDSLOT,a.XIDSQN,a.OBJECT_ID,b.OBJECT_NAME,a.SESSION_ID,a.ORACLE_USERNAME,a.OS_USER_NAME,a.PROCESS,LOCKED_MODE from
GV$LOCKED_OBJECT a,dba_objects b where a.object_id=b.object_id and ORACLE_USERNAME like '%ASP01%' order by 8;
以分区表(SEG_TEST_SINGLE_PARTITON)作为对象名称
的结果 "INST_ID" "XIDUSN" "XIDSLOT" "XIDSQN" "OBJECT_ID" "OBJECT_NAME" "SESSION_ID" "ORACLE_USERNAME" "OS_USER_NAME" "PROCESS" "LOCKED_MODE"
3 58 16 424487 3235818 "PLAN_TABLE$" 2447 "ASP01" "z013" "15140" 3
3 139 5 56366 3929061 "SEG_TEST_SINGLE_PARTITION" 3339 "ASP01" "z013" "31624" 3
3 139 5 56366 3929063 "SEG_TEST_SINGLE_PARTITION" 3339 "ASP01" "z013" "31624" 3
现在,我们想知道为什么我们使用相同的session_id(3339)将单个表的表锁定两次,这会导致插入java多线程或批量插入时出现长时间延迟,有时根据数据大小挂起?
答案 0 :(得分:0)
我们的项目遇到了类似的问题。我们增加了INITRANS
。
我不太确定,但高级技术拱门告诉我,oracle 12c有一个错误。此外,不推荐使用MAXTRANS
。 https://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses007.htm
因此,我们手动增加了所有分区的INITRANS
值,然后moved
分区,以便设置适用。
我们理解的问题是,发生数据块的并发更新超出了INITRANS
设置允许的范围。
我不确定准确的语法,但它类似于:
ALTER TABLE SEG_TEST_SINGLE_PARTITION MOVE PARTITION PWKLY_ORDR_POR02 INITRANS 10;
ALTER TABLE SEG_TEST_SINGLE_PARTITION MODIFY PARTITION PWKLY_ORDR_POR02 REBUILD INDEX;