我正在尝试编写一个自动重试事务" monkey patch"光滑的(1.0,不幸的是)。此外,我希望它只重试某些类型的异常。不幸的是,我一直在运行类型擦除的问题。根据我的理解,我想要做的是最终混合运行时和编译时成语,但在这一点上,我所有的想法。我尝试使用反射吗?
object SessionSupport {
/**
* Patches the session object to add trnansaction serializable
* with automatic retry
*/
implicit class SlickSessionWrapper(session:Session) {
private val logger = LoggerFactory.getLogger(getClass)
val MAX_RETRIES = 3
// UNFORTUNATELY I CANT SEEM TO GET RID OF THE UNCHECKED WARNING.
// As such, the type check is alwasy going to "pass" for ANY throwable
def withRetryingSerializableTransaction[A, T <: Throwable ](f: => A)(implicit retryCt:Int = 0):A = {
val res:Try[A] = session.withTransaction {
session.conn.setTransactionIsolation(
java.sql.Connection.TRANSACTION_SERIALIZABLE
)
Try(f)
}
res match {
case Success(v) => v
case Failure(thr) => {
if(thr.isInstanceOf[T] && retryCt < MAX_RETRIES) { // type erasure here!!!
logger.debug(s"Caught ${thr.toString}, retrying")
withRetryingSerializableTransaction[A, T](f)(retryCt + 1)
} else {
logger.error(s"Caught ${thr.toString}. Rethrowing", thr)
throw thr
}
}
}
}
}
}
答案 0 :(得分:1)
def withRetryingSerializableTransaction[A, T <: Throwable : Manifest]
然后代替thr.isInstanceOf[T]
,执行manifest.runtimeClass.isInstance(thr)