首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Squeryl中设置事务隔离级别

在Squeryl中设置事务隔离级别
EN

Stack Overflow用户
提问于 2011-11-25 18:08:41
回答 2查看 1.7K关注 0票数 3

如何使用Squeryl设置事务隔离级别?

例如,现在我正在使用Postgresql,需要对特定的单个事务进行可序列化的隔离。我使用普通的Squeryl和Squeryl-记录与电梯网络框架。

当然,对于整个会话(而不是单个事务)的其他数据库,其他数据库可能需要其他隔离级别,因此更可取的是一般的答案。

更新:

最后,我得到了代码的修改版本:

代码语言:javascript
运行
复制
def transactionWith[T](isolation: Int)(block: => T): T =
  transaction {
    val connection = Session.currentSession.connection
    connection.rollback // isolation cannot be changed in the middle of a tx
    connection.setTransactionIsolation(isolation)
    block
  }

问题是,如果事务已经启动,则不能更改隔离级别。对我来说是这样,如果没有回滚,我会得到:

org.postgresql.util.PSQLException:无法更改事务中间的事务隔离级别。

只要我使用的是事务{}而不是inTransaction{},我认为立即回滚不会有什么害处。

在事务{}提交或回滚之后,但在连接返回到连接池之前,应重置隔离级别。我不知道该怎么做。但在我的示例中,c3p0连接池似乎重置了隔离级别,每个事务{}都以默认隔离级别启动,即使我自己从未清理过它们。

我不太高兴的是,当有冲突的时候。我想专门捕获这样的异常并重试事务。但这只是一个一般的运行时异常:

java.lang.RuntimeException:执行语句时的异常:错误:由于并发更新,无法序列化访问

它封装了另一个异常,不幸的是,它也是泛型的(org.postgresql.util.PSQLException)。

这并不完美,但在Squeryl有望获得事务隔离支持之前,它就能完成这项工作。我使用了上面的代码与Squeryl 0.9.4。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-25 23:03:28

现在,这将是一个有点手动的过程。如果整个会话都需要它,那么我想您可以简单地在SessionFactory中设置适当的级别,即

代码语言:javascript
运行
复制
SessionFactory.concreteFactory = Some(()=> {
  val connection = java.sql.DriverManager.getConnection("...")
  connection.setTransactionIsolation(...)
  Session.create(connection, new PostgreSqlAdapter)
 })

对于单个事务来说,这会稍微困难一些。您可以使用Session.currentSession或Session.currentSessionOption访问当前会话,并且必须在事务发生之前设置隔离级别,然后再将其设置回。当然,创建您自己的函数并不太困难,因为它就是这样做的:

代码语言:javascript
运行
复制
def transactionWith(isolation: Int)(block: => T): T = {
  trasaction{
    val connection = Session.currentSession.connection
    val oldIsolation = connection.getTransactionIsolation()
    connection.setTransactionIsolation(isolation)
    try {
      block
    } finally {
      connection.setTransactionIsolation(oldIsolation)
    }
  }
}

然后你就会把它当作

代码语言:javascript
运行
复制
transactionWith(Connection.TRANSACTION_SERIALIZABLE){
   from(blablabla)(......)
}

我认为这是可行的,但是( a)我不完全确定何时应该设置隔离级别,我假设在执行任何其他语句之前在当前事务中设置隔离级别将有效;( b)我没有尝试编译上面的内容,因此可能会出现语法错误。不管怎么说,我想这会给你一个大致的想法。

票数 3
EN

Stack Overflow用户

发布于 2012-04-03 23:43:50

关于异常:org.postgresql.util.PSQLException扩展了java.sql.SQLException,它有一个getSQLState()方法。这种序列化失败导致的异常将从此方法返回"40001"

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8272848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档