【发布时间】:2012-06-10 23:42:23
【问题描述】:
给定以下代码:我们需要锁定模型,然后启动一个事务(这可能会引发异常,因此我们必须确保释放锁),然后执行类似获取数据库连接的操作(这可能抛出异常),然后做一些可能抛出需要恢复事务的异常的事情。这是 Java 6,所以我们没有可用的 Java 7 好东西。
SomeClass someMethod()
throws SomeException {
acquireWriteLock();
try {
startTransaction();
try {
DBConnection d = openDBConnection();
try {
doStuff(d);
commitTransaction();
} finally {
d.close();
}
} catch (SomeException e) {
handleSomeException(e);
revertTransaction();
throw e;
} catch (Throwable t) {
revertTransaction(); // Error: method must return a value of SomeClass
}
} finally {
releaseWriteLock();
}
}
是否可以将其重写为更具可读性和更少冗长?
只是为了好玩:当您看到以下内容时,您会怎么做?
DBConnection d = null;
try {
acquireWriteLock();
startTransaction();
d = openDBConnection();
try {
doStuff(d);
commitTransaction();
} catch (SomeException e) {
handleSomeException(e);
revertTransaction();
}
} finally {
d.close();
releaseWriteLock();
}
【问题讨论】:
-
除非您升级到 Java 7,否则您无能为力。
-
在发生异常的情况下,您的第一个代码块是否不会在事务可以恢复之前关闭 dtb 连接?在这方面,我认为第二个代码块看起来更好,更安全。还是我错过了什么?
-
说实话,比起升级到 Java 7,我宁愿在 Erlang 中重做整个事情,使用无共享通信顺序进程,再也不用担心线程安全。但这也不会发生。
-
方法名称已更改,原因与专有信息有关;它根本不是真正的 DBConnection,所以很抱歉误导人们认为问题可以通过让数据库处理事务来轻松解决。
-
@MarkLutton 对。不过,我会成为好奇的人。如果您有一两分钟的空闲时间,您能否向我解释一下为什么第一个街区比第二个街区更受欢迎?是因为
openDBConnection()可能会抛出一些必须处理的有意义的东西吗?如果是这种情况,它可能只是在第二个块中向下推一行,它会是一样的。这让我难以置信,我只是想得到它:)。
标签: java raii exception-safety