Sql 来自并发访问的DataIntegrityViolationException
我有一个表,它在两列上有唯一的索引约束。我检查并插入数据库的代码如下:Sql 来自并发访问的DataIntegrityViolationException,sql,slick,Sql,Slick,我有一个表,它在两列上有唯一的索引约束。我检查并插入数据库的代码如下: def createNewEntry(myTableType: MyTableType) = database withSession { implicit session: Session => val autoInc = myTableElems returning myTableElems.map(_.elemId) getElemForId(myTableType.elemId) match {
def createNewEntry(myTableType: MyTableType) = database withSession { implicit session: Session =>
val autoInc = myTableElems returning myTableElems.map(_.elemId)
getElemForId(myTableType.elemId) match {
case Some(oldTableType) =>
if (oldTableType.isModified(myTableType))
myTableElems.insert(myTableType.copy(version = oldTableType.version + 1))
case None =>
autoInc.insert(myTableType)
}
getElemForId(myTableType.elemId)
}
上述代码是否有可能由于上述方法的并发访问而导致DataIntegrityViolation异常?我在一个名为name的列和另一个名为version的列上定义了一个唯一索引。每次调用这个createNewEntry方法时,我都会检查是否存在。如果存在,我会复制所有内容,增加版本并将新版本插入数据库
由于我使用Slick进行数据库访问,因此上述方法在数据库事务上下文和自动提交模式下工作
数据库中包含条目的我的表如下所示:
id name version
1 abc 1
2 xyz 1
3 abc 2
名称和版本已强制执行唯一索引约束
现在的问题是,有没有可能出现DataIntegrityViolation异常的情况?我应该防范吗?是的,以这种方式递增会导致问题-两个并发调用可能会派生相同的新版本号,而后者将因PK/Unique约束冲突而失败。而是使用RDBMS的本机增量机制,例如MySql中的
AUTO_increment
,或Sql Server+Oracle中的Identity
。(事务通常是读取提交的
隔离,这不会阻止其他并发读卡器获得相同的版本)版本不能是自动增量字段,因为这需要每个条目执行!除了锁定上述代码之外,还有什么其他可能性?请参阅上面我的帖子中的表格结构!