我当前的设置使用BDBJE 4.1.10。我有10个线程试图将关键字对象写入数据库。
数据的本质是辅助键-存储和项目有很多重复项。意思是,许多关键字对象映射到相同的商店和商品条目。
LOCK_N_LOCK_TABLES为7
@Entity
公共类关键字实现了可序列化的{
@PrimaryKey
private String key;
@SecondaryKey(relate = Relationship.MANY_TO_MANY)
private List<Long> stores = new ArrayList<Long>();
@SecondaryKey(relate = Relationship.MANY_TO_MANY)
private List<Long> items = new ArrayList<Long>();
}
大约有10%(总共100,000个)辅助数据库插入失败,并显示LockTimeoutException。
看看stacktrace,我知道线程6在放弃之前等待了2000ms的锁,还有3个线程在等待。
基本上,所有者线程(线程10)正在执行的操作要花费2000ms以上的时间。线程6试图在辅助数据库项目中插入一条记录。
Stacktrace:
com.sleepycat.je.LockTimeoutException: (JE 4.1.10) Lock expired.
Locker 786527582 -1_fileChannelTaskExecutor-6_ThreadLocker: waited for lock on database=persist#faceted_store#com.xyzq.seo.bdb.entity.Keyword#items
LockAddr:43409842 node=281964 type=WRITE grant=WAIT_NEW timeoutMillis=2000 startTime=1538759059393 endTime=1538759061393
Owners: [<LockInfo locker="786774600 -1_fileChannelTaskExecutor-10_ThreadLocker" type="WRITE"/>]
Waiters:
[
<LockInfo locker="1270863098 -1_fileChannelTaskExecutor-9_ThreadLocker" type="WRITE"/>,
<LockInfo locker="1244207474 -1_fileChannelTaskExecutor-4_ThreadLocker" type="WRITE"/>,
<LockInfo locker="1391625295 -1_fileChannelTaskExecutor-1_ThreadLocker" type="WRITE"/>
]
at com.sleepycat.je.txn.LockManager.newLockTimeoutException(LockManager.java:608
at com.sleepycat.je.txn.LockManager.makeTimeoutMsgInternal(LockManager.java:567
at com.sleepycat.je.txn.SyncedLockManager.makeTimeoutMsg(SyncedLockManager.java:75
at com.sleepycat.je.txn.LockManager.lockInternal(LockManager.java:385
at com.sleepycat.je.txn.LockManager.lock(LockManager.java:272
at com.sleepycat.je.txn.BasicLocker.lockInternal(BasicLocker.java:134
at com.sleepycat.je.txn.Locker.lock(Locker.java:453
at com.sleepycat.je.dbi.CursorImpl.lockDupCountLN(CursorImpl.java:2768
at com.sleepycat.je.tree.Tree.insertDuplicate(Tree.java:2847
at com.sleepycat.je.tree.Tree.insert(Tree.java:2488
at com.sleepycat.je.dbi.CursorImpl.put(CursorImpl.java:1209
at com.sleepycat.je.Cursor.putAllowPhantoms(Cursor.java:1799
at com.sleepycat.je.Cursor.putNoNotify(Cursor.java:1756
at com.sleepycat.je.Cursor.putNotify(Cursor.java:1689
at com.sleepycat.je.Cursor.putInternal(Cursor.java:1626
at com.sleepycat.je.SecondaryDatabase.insertKey(SecondaryDatabase.java:984
at com.sleepycat.je.SecondaryDatabase.updateSecondary(SecondaryDatabase.java:909
at com.sleepycat.je.SecondaryTrigger.databaseUpdated(SecondaryTrigger.java:41
at com.sleepycat.je.Database.notifyTriggers(Database.java:2016
at com.sleepycat.je.Cursor.putNotify(Cursor.java:1702
at com.sleepycat.je.Cursor.putInternal(Cursor.java:1626
at com.sleepycat.je.Database.putInternal(Database.java:1186
at com.sleepycat.je.Database.put(Database.java:1058
at com.sleepycat.persist.PrimaryIndex.putNoReturn(PrimaryIndex.java:479
at com.sleepycat.persist.PrimaryIndex.putNoReturn(PrimaryIndex.java:442
at com.xyzq.bdb.cache.da.impl.BDBDataAccessor.create(BDBDataAccessor.java:77)
我尝试了以下
减少了锁定时间。希望获胜者在完成将记录插入数据库后立即释放该锁。
捕获LockTimeOutException,然后稍后尝试重新插入关键字。这可行,但它是手动的,需要时间。 10%的关键字由于LockTimeOutException而失败。 100k中约有10k。
我有几个问题:
可以写入数据库的线程数是否受到限制?还是取决于数据?
如果我将实体建模为纯键值对而不是使用辅助数据库会有所帮助吗?
@Entity
关键字
@PrimaryKey
- key
@Entity
项目
-id
-key [reference to Keyword Obj]
@Entity
商店
- id
- key [reference to Keyword obj.]
谢谢!