All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tsc9526.monalisa.orm.Tx Maven / Gradle / Ivy

There is a newer version: 2.2.0
Show newest version
/*******************************************************************************************
 *	Copyright (c) 2016, zzg.zhou([email protected])
 * 
 *  Monalisa is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU Lesser General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.

 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU Lesser General Public License for more details.

 *	You should have received a copy of the GNU Lesser General Public License
 *	along with this program.  If not, see .
 *******************************************************************************************/
package com.tsc9526.monalisa.orm;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.tsc9526.monalisa.orm.datasource.DBConfig;
import com.tsc9526.monalisa.tools.cache.TransactionalCacheManager;
import com.tsc9526.monalisa.tools.datatable.DataMap;
import com.tsc9526.monalisa.tools.misc.MelpException;

/**
 * 
 * 以事务执行数据库操作

* * * Tx.execute(new Atom(){
*   public int execute()throws Throwable{
*     ... 数据库操作代码
*   }
* );
*
* @author zzg.zhou([email protected]) */ public class Tx { public final static String CONTEXT_CURRENT_USERID="CONTEXT_CURRENT_USERID"; public static interface Atom{ public T execute()throws Throwable; } private static class CI{ Connection conn; boolean autoCommit; CI(Connection conn) throws SQLException{ this.conn=conn; this.autoCommit=conn.getAutoCommit(); } } private static ThreadLocal tx =new ThreadLocal(); private static ThreadLocal context=new ThreadLocal(); public static Object getContext(String key){ DataMap m=context.get(); if(m!=null){ return m.get(key); }else{ return null; } } public static void removeContext(String key){ DataMap m=context.get(); if(m!=null){ m.remove(key); } } public static void putContext(String key,Object value){ DataMap m=context.get(); if(m==null){ m=new DataMap(); context.set(m); } m.put(key, value); } public static void clearContext(){ if(context.get()!=null){ context.remove(); } } public static Tx getTx(){ return tx.get(); } /** * * @return Transaction context. Throw RuntimeException if the transaction started by other method. */ public static Tx begin(){ Tx x=tx.get(); if(x==null){ x=new Tx(); tx.set(x); return x; }else{ throw new RuntimeException("Begin error, transaction started by other method!"); } } public static void commit() throws SQLException{ Tx x=tx.get(); if(x!=null){ x.doCommit(); }else{ throw new RuntimeException("Commit error, transaction not start, call begin first!"); } } public static void rollback(){ Tx x=tx.get(); if(x!=null){ x.doRollback(); }else{ throw new RuntimeException("Rollback error, transaction not start, call begin first!"); } } public static void close(){ Tx x=tx.get(); if(x!=null){ tx.remove(); x.doClose(); } } /** * Execute the run() method in transaction * * @param x Atom * @param T int / int[] * @return Number of rows affected */ public static T execute(Atom x){ return execute(x,-1); } /** * Execute the run() method in transaction * * @param x Atom * @param level setTransactionIsolation * @param T int / int[] * @return Number of rows affected */ public static T execute(Atom x, int level){ Tx tx=getTx(); if(tx==null){ tx=begin(); try{ if(level>-1){ tx.setTransactionIsolation(level); } T r=x.execute(); commit(); return r; }catch(Throwable e){ rollback(); return MelpException.throwRuntimeException(e); }finally{ close(); } }else{ try{ T r=x.execute(); return r; }catch(Throwable e){ return MelpException.throwRuntimeException(e); } } } private Map hcs=new HashMap(); private int level=-1; private String txid=UUID.randomUUID().toString().replace("-","").toLowerCase(); private TransactionalCacheManager tcm = new TransactionalCacheManager(); private Tx(){ } public String getTxid(){ return txid; } public Connection getConnection(DBConfig db) throws SQLException{ String key=db.getKey(); CI ci=hcs.get(key); if (ci==null) { Connection conn=db.getDataSource().getConnection(); ci=new CI(conn); conn.setAutoCommit(false); if(level>-1){ conn.setTransactionIsolation(level); } hcs.put(key, ci); } return ci.conn; } public void setTransactionIsolation(int level)throws SQLException{ this.level=level; for(CI ci:hcs.values()){ ci.conn.setTransactionIsolation(level); } } public void doCommit() throws SQLException{ for(CI ci:hcs.values()){ ci.conn.commit(); } tcm.commit(); } public void doRollback(){ try{ for(CI ci:hcs.values()){ ci.conn.rollback(); } tcm.rollback(); }catch(SQLException e){ throw new RuntimeException(e); } } public void doClose(){ try{ for(CI ci:hcs.values()){ ci.conn.setAutoCommit(ci.autoCommit); ci.conn.close(); } }catch(SQLException e){ throw new RuntimeException(e); }finally{ hcs.clear(); } } public TransactionalCacheManager getTxCacheManager() { return tcm; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy