Bee*_*Bee 5 java transactions jdbc java-8
我正在用Java 8编写一个事务.首先,我的代码是这样的.
try (Connection conn = DAOUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(addSubscriptionSql)) {
conn.setAutoCommit(false);
//do work
conn.commit();
} catch (SQLException e) {
e.printStackTrace(); //handle error
}
Run Code Online (Sandbox Code Playgroud)
但是因为我应该在事务失败的情况下回滚,所以我不得不像这样更改代码.注意这两个try块.
try (Connection conn = DAOUtil.getConnection()) {
try (PreparedStatement ps = conn.prepareStatement(addSubscriptionSql)) {
conn.setAutoCommit(false);
//do work
conn.commit();
} catch (SQLException e) {
conn.rollback();
e.printStackTrace(); //handle error
}
} catch (SQLException e) {
e.printStackTrace(); //handle error
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,有更好的(我的意思是更简单)这样做的方式吗?我可以用一个try块实现这个目的吗?
Hol*_*ger 10
您可以使用
try(Connection conn = DAOUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(addSubscriptionSql);
AutoCloseable finish = conn::rollback) {
conn.setAutoCommit(false);
//do work
conn.commit();
}
Run Code Online (Sandbox Code Playgroud)
这将始终调用rollback(),但在成功完成后commit(),回滚将变为无操作,因为它将状态重置为上次成功完成后的状态commit()...
因为AutoCloseable声明要抛出Exception将需要处理这种广泛的异常类型.它可以使用在其他情况下可能有用的自定义类型进行修复:
interface SQLCloseable extends AutoCloseable {
@Override public void close() throws SQLException;
}
Run Code Online (Sandbox Code Playgroud)
...
try(Connection conn = DAOUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(addSubscriptionSql);
SQLCloseable finish = conn::rollback) {
conn.setAutoCommit(false);
//do work
conn.commit();
}
Run Code Online (Sandbox Code Playgroud)
现在,只SQLException强制处理异常类型.
如果您不喜欢rollback()被无条件调用的想法,那么解决方案就会变得不那么优雅:
boolean[] success = { false };
try(Connection conn = DAOUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(addSubscriptionSql);
SQLCloseable finish = () -> { if(!success[0]) conn.rollback(); }) {
conn.setAutoCommit(false);
//do work
conn.commit();
success[0] = true;
}
Run Code Online (Sandbox Code Playgroud)
如果在结束时重置自动提交状态,则可以将其用作回滚必要性的指示符:
try(Connection conn = DAOUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(addSubscriptionSql);
SQLCloseable finish = () -> { if(!conn.getAutoCommit()) conn.rollback(); }) {
conn.setAutoCommit(false);
//do work
conn.commit();
conn.setAutoCommit(true);
}
Run Code Online (Sandbox Code Playgroud)
我可以用一个try块实现这个目的吗?
不,因为您的conn对象在catch您的try-with-resources块中不可用.如果要在执行时捕获异常PreparedStatement并显式执行a,conn.rollback()则回滚将必须在try创建conn对象的try-with-resources中发生(即,使用第二个嵌套try块进行PreparedStatement调用).
| 归档时间: |
|
| 查看次数: |
2306 次 |
| 最近记录: |