首先说一下 Jfinal 事务的配置,然后再说原理。
配置 :
jfinal 对事务的配置很简单。有两种配置方式
1.直接在 方法上增加拦截器@Before(Tx.class)
2.使用 Db.tx(atom)
eg:
public void tx(){
Db.tx(new IAtom() {
@Override
public boolean run() throws SQLException {
Db.update("update blog set content='ddd' where title='test4'");
return false;
}
});
}
原理:
事务是数据库提供的一种控制数据存储的一种方法,当一部分数据保存失败以后,以前的数据也自动清空,恢复到事务执行以前状态。保证的数据的清洁。
mysql 数据操作有两种状态,一种是手动,一种是自动。获取提交的方式:
conn = config.getConnection(); autoCommit = conn.getAutoCommit();
使用事务的原理就是:将提交方式设置成手动状态,将事务中的所有语句的执行结果,在事务完成以后统一赋给数据库,在事务结束之前不对数据库做操作。一旦数据操作出现问题,则停止事务,不做处理
1、对于第一种方式
Config config = getConfigWithTxConfig(ai);
if (config == null)
config = DbKit.getConfig();
Connection conn = config.getThreadLocalConnection();
if (conn != null) { // Nested transaction support
try {
if (conn.getTransactionIsolation() < getTransactionLevel(config))
conn.setTransactionIsolation(getTransactionLevel(config));
ai.invoke();
return ;
} catch (SQLException e) {
throw new ActiveRecordException(e);
}
}
Boolean autoCommit = null;
try {
conn = config.getConnection();
autoCommit = conn.getAutoCommit();
config.setThreadLocalConnection(conn);
conn.setTransactionIsolation(getTransactionLevel(config)); // conn.setTransactionIsolation(transactionLevel);
conn.setAutoCommit(false);
ai.invoke();
conn.commit();
} catch (NestedTransactionHelpException e) {
if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
} catch (Throwable t) {
if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
throw new ActiveRecordException(t);
}
finally {
try {
if (conn != null) {
if (autoCommit != null)
conn.setAutoCommit(autoCommit);
conn.close();
}
} catch (Throwable t) {
t.printStackTrace(); // can not throw exception here, otherwise the more important exception in previous catch block can not be thrown
}
finally {
config.removeThreadLocalConnection(); // prevent memory leak
}
}
}
}
2、针对第二种方式
Connection conn = config.getThreadLocalConnection();
if (conn != null) { // Nested transaction support
try {
if (conn.getTransactionIsolation() < transactionLevel)
conn.setTransactionIsolation(transactionLevel);
boolean result = atom.run();
if (result)
return true;
throw new NestedTransactionHelpException("Notice the outer transaction that the nested transaction return false"); // important:can not return false
}
catch (SQLException e) {
throw new ActiveRecordException(e);
}
}
Boolean autoCommit = null;
try {
conn = config.getConnection();
autoCommit = conn.getAutoCommit();
config.setThreadLocalConnection(conn);
conn.setTransactionIsolation(transactionLevel);
conn.setAutoCommit(false);
boolean result = atom.run();
if (result)
conn.commit();
else
conn.rollback();
return result;
} catch (NestedTransactionHelpException e) {
if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
return false;
} catch (Throwable t) {
if (conn != null) try {conn.rollback();} catch (Exception e1) {e1.printStackTrace();}
throw t instanceof RuntimeException ? (RuntimeException)t : new ActiveRecordException(t);
} finally {
try {
if (conn != null) {
if (autoCommit != null)
conn.setAutoCommit(autoCommit);
conn.close();
}
} catch (Throwable t) {
t.printStackTrace(); // can not throw exception here, otherwise the more important exception in previous catch block can not be thrown
} finally {
config.removeThreadLocalConnection(); // prevent memory leak
}
}
}
public boolean tx(int transactionLevel, IAtom atom) {
return tx(config, transactionLevel, atom);
}
/**
* Execute transaction with default transaction level.
* @see #tx(int, IAtom)
*/
public boolean tx(IAtom atom) {
return tx(config, config.getTransactionLevel(), atom);
}
/**
* Find Record by cache.
* @see #find(String, Object...)
* @param cacheName the cache name
* @param key the key used to get date from cache
* @return the list of Record
*/
public List<Record> findByCache(String cacheName, Object key, String sql, Object... paras) {
ICache cache = config.getCache();
List<Record> result = cache.get(cacheName, key);
if (result == null) {
result = find(sql, paras);
cache.put(cacheName, key, result);
}
return result;
事务的四种隔离级别
http://blog.chinaunix.net/uid-24111901-id-2627894.html