package org.nutz.dao.impl.sql.run;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;
import javax.sql.DataSource;
import org.nutz.dao.ConnCallback;
import org.nutz.dao.DaoException;
import org.nutz.dao.impl.DaoRunner;
import org.nutz.lang.Lang;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.trans.Trans;
import org.nutz.trans.Transaction;
public class NutDaoRunner implements DaoRunner {
private static final Log log = Logs.get();
public void run(DataSource dataSource, ConnCallback callback) {
Transaction t = Trans.get();
// 有事务
if (null != t) {
Connection conn = null;
Savepoint sp = null;
try {
conn = t.getConnection(dataSource);
sp = conn.setSavepoint();
callback.invoke(conn);
}
catch (Exception e) {
if (e instanceof DaoException)
if (null != conn
&& null != e.getCause()
&& e.getCause() instanceof SQLException) {
try {
if (null == sp)
conn.rollback();
else
conn.rollback(sp);
}
catch (SQLException e1) {
if (log.isErrorEnabled())
log.error(e1);
}
}
throw new DaoException(Lang.unwrapThrow(e));
}
}
// 无事务
else {
Connection conn = null;
boolean old = false;
// 开始一个连接
try {
conn = dataSource.getConnection();
// 多条语句运行,将自动提交设为 false
old = conn.getAutoCommit();
conn.setAutoCommit(false);
// 开始循环运行
callback.invoke(conn);
// 完成提交
if (!conn.getAutoCommit())
conn.commit();
}
// 异常回滚
catch (Exception e) {
try {
if (conn != null) // 高并发时,从数据库连接池获取连接就已经抛错误,所以conn可能为null的
conn.rollback();
}
catch (SQLException e1) {}// TODO 简单记录一下?
throw new DaoException(e);
}
// 保证释放资源
finally {
if (null != conn) {
// 恢复链接自动提交设定
// 这种事情也要NutDao自己干?
try {
if (old != conn.getAutoCommit())
conn.setAutoCommit(old);
}
catch (SQLException autoE) {
if (log.isWarnEnabled())
log.warn("Fail to restore autoCommet to '" + old + "'", autoE);
}
// 关闭链接
try {
conn.close();
}
catch (SQLException closeE) {
if (log.isWarnEnabled())
log.warn("Fail to close connection!", closeE);
}
}
}
}
}
}