![JAR search and dependency download from the Maven repository](/logo.png)
com.tsc9526.monalisa.orm.Tx Maven / Gradle / Ivy
/*******************************************************************************************
* 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