【发布时间】:2017-05-03 00:56:39
【问题描述】:
我在 Oracle 11g 中创建了一个分区表,并尝试使用 Java 批处理作业中的多线程插入记录。 假设我有 10 个线程,并且每个线程都想同时插入/更新 100 万条记录,或者在没有线程的情况下批量插入一段时间,在这两种情况下,我们的表都被 oracle 锁定为同一个会话。如果我们有 10 个线程,那么我们为 1 个同一个表的 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
所以到目前为止我没有锁定上面创建的表,现在我将运行插入查询而不提交,并将检查来自 sql 开发人员(或任何地方)的锁定 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) 为单个表获取 tablelock,这会在通过 java 多线程或 Bulk insert 插入时导致长时间延迟,并且有时会因数据大小而挂起?
【问题讨论】:
标签: oracle partitioning